diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index bdef820..4513497 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,3 +1,3 @@
{
- "recommendations": ["svelte.svelte-vscode"]
+ "recommendations": ["svelte.svelte-vscode", "dbaeumer.vscode-eslint", "editorconfig.editorconfig"]
}
diff --git a/README.md b/README.md
index e6cd94f..d68e84a 100644
--- a/README.md
+++ b/README.md
@@ -1,47 +1,7 @@
-# Svelte + TS + Vite
+# Svelte + TS + Vite + Electron
-This template should help get you started developing with Svelte and TypeScript in Vite.
+This template should help get you started developing with Svelte, TypeScript and Vite in Electron.
## Recommended IDE Setup
-[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
-
-## Need an official Svelte framework?
-
-Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
-
-## Technical considerations
-
-**Why use this over SvelteKit?**
-
-- It brings its own routing solution which might not be preferable for some users.
-- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
-
-This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
-
-Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate.
-
-**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
-
-Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information.
-
-**Why include `.vscode/extensions.json`?**
-
-Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project.
-
-**Why enable `allowJs` in the TS template?**
-
-While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant.
-
-**Why is HMR not preserving my local component state?**
-
-HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr).
-
-If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR.
-
-```ts
-// store.ts
-// An extremely simple external store
-import { writable } from 'svelte/store'
-export default writable(0)
-```
+[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) + [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + [EditorConfig](https://marketplace.visualstudio.com/items?itemName=editorconfig.editorconfig).
diff --git a/build/entitlements.mac.plist b/build/entitlements.mac.plist
new file mode 100644
index 0000000..38c887b
--- /dev/null
+++ b/build/entitlements.mac.plist
@@ -0,0 +1,12 @@
+
+
+
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+ com.apple.security.cs.allow-dyld-environment-variables
+
+
+
diff --git a/build/icon.icns b/build/icon.icns
new file mode 100644
index 0000000..28644aa
Binary files /dev/null and b/build/icon.icns differ
diff --git a/build/icon.ico b/build/icon.ico
new file mode 100644
index 0000000..72c391e
Binary files /dev/null and b/build/icon.ico differ
diff --git a/build/icon.png b/build/icon.png
new file mode 100644
index 0000000..cf9e8b2
Binary files /dev/null and b/build/icon.png differ
diff --git a/electron-builder.yml b/electron-builder.yml
new file mode 100644
index 0000000..27fb28d
--- /dev/null
+++ b/electron-builder.yml
@@ -0,0 +1,43 @@
+appId: com.electron.app
+productName: electron-svelte
+directories:
+ buildResources: build
+files:
+ - '!**/.vscode/*'
+ - '!src/*'
+ - '!electron.vite.config.{js,ts,mjs,cjs}'
+ - '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'
+ - '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'
+ - '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}'
+asarUnpack:
+ - resources/**
+win:
+ executableName: electron-svelte
+nsis:
+ artifactName: ${name}-${version}-setup.${ext}
+ shortcutName: ${productName}
+ uninstallDisplayName: ${productName}
+ createDesktopShortcut: always
+mac:
+ entitlementsInherit: build/entitlements.mac.plist
+ extendInfo:
+ - NSCameraUsageDescription: Application requests access to the device's camera.
+ - NSMicrophoneUsageDescription: Application requests access to the device's microphone.
+ - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
+ - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
+ notarize: false
+dmg:
+ artifactName: ${name}-${version}.${ext}
+linux:
+ target:
+ - AppImage
+ - snap
+ - deb
+ maintainer: electronjs.org
+ category: Utility
+appImage:
+ artifactName: ${name}-${version}.${ext}
+npmRebuild: false
+publish:
+ provider: generic
+ url: https://example.com/auto-updates
diff --git a/electron.vite.config.ts b/electron.vite.config.ts
new file mode 100644
index 0000000..debac16
--- /dev/null
+++ b/electron.vite.config.ts
@@ -0,0 +1,11 @@
+import { defineConfig } from 'vite'
+import { svelte } from '@sveltejs/vite-plugin-svelte'
+
+// https://vite.dev/config/
+export default {
+ main: defineConfig({}),
+ preload: defineConfig({}),
+ renderer: defineConfig({
+ plugins: [svelte()]
+ })
+}
diff --git a/package.json b/package.json
index ebe650b..cbcdeac 100644
--- a/package.json
+++ b/package.json
@@ -1,21 +1,44 @@
{
"name": "electron-svelte",
+ "description": "A template to make desktops applications using svelte, vite and electron. Based on alex8088's electron-vite.",
"private": true,
"version": "0.0.0",
"type": "module",
+ "main": "./out/main/index.js",
"scripts": {
- "dev": "vite",
- "build": "vite build",
- "preview": "vite preview",
- "check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json"
+ "format": "prettier --plugin prettier-plugin-svelte --write .",
+ "lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
+ "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
+ "svelte-check": "svelte-check --tsconfig ./tsconfig.json",
+ "typecheck": "npm run typecheck:node && npm run svelte-check",
+ "start": "electron-vite preview",
+ "dev": "electron-vite dev",
+ "build": "npm run typecheck && electron-vite build",
+ "postinstall": "electron-builder install-app-deps",
+ "build:unpack": "npm run build && electron-builder --dir",
+ "build:win": "npm run build && electron-builder --win",
+ "build:mac": "npm run build && electron-builder --mac",
+ "build:linux": "npm run build && electron-builder --linux"
},
"devDependencies": {
+ "@eslint/js": "^9.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tsconfig/svelte": "^5.0.4",
+ "electron": "^33.2.1",
+ "electron-builder": "^25.1.8",
+ "electron-vite": "^2.3.0",
+ "eslint": "^9.16.0",
+ "globals": "^15.13.0",
+ "prettier-plugin-svelte": "^3.3.2",
"svelte": "^5.2.7",
"svelte-check": "^4.1.0",
"tslib": "^2.8.1",
"typescript": "~5.6.2",
+ "typescript-eslint": "^8.17.0",
"vite": "^6.0.1"
+ },
+ "dependencies": {
+ "@electron-toolkit/preload": "^3.0.1",
+ "@electron-toolkit/utils": "^3.0.0"
}
}
diff --git a/resources/icon.png b/resources/icon.png
new file mode 100644
index 0000000..cf9e8b2
Binary files /dev/null and b/resources/icon.png differ
diff --git a/src/main/index.ts b/src/main/index.ts
new file mode 100644
index 0000000..06e06b4
--- /dev/null
+++ b/src/main/index.ts
@@ -0,0 +1,74 @@
+import { app, shell, BrowserWindow, ipcMain } from 'electron'
+import { join } from 'path'
+import { electronApp, optimizer, is } from '@electron-toolkit/utils'
+import icon from '../../resources/icon.png?asset'
+
+function createWindow(): void {
+ // Create the browser window.
+ const mainWindow = new BrowserWindow({
+ width: 900,
+ height: 670,
+ show: false,
+ autoHideMenuBar: true,
+ ...(process.platform === 'linux' ? { icon } : {}),
+ webPreferences: {
+ preload: join(__dirname, '../preload/index.js'),
+ sandbox: false
+ }
+ })
+
+ mainWindow.on('ready-to-show', () => {
+ mainWindow.show()
+ })
+
+ mainWindow.webContents.setWindowOpenHandler((details) => {
+ shell.openExternal(details.url)
+ return { action: 'deny' }
+ })
+
+ // HMR for renderer base on electron-vite cli.
+ // Load the remote URL for development or the local html file for production.
+ if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
+ mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
+ } else {
+ mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
+ }
+}
+
+// This method will be called when Electron has finished
+// initialization and is ready to create browser windows.
+// Some APIs can only be used after this event occurs.
+app.whenReady().then(() => {
+ // Set app user model id for windows
+ electronApp.setAppUserModelId('com.electron')
+
+ // Default open or close DevTools by F12 in development
+ // and ignore CommandOrControl + R in production.
+ // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
+ app.on('browser-window-created', (_, window) => {
+ optimizer.watchWindowShortcuts(window)
+ })
+
+ // IPC test
+ ipcMain.on('ping', () => console.log('pong'))
+
+ createWindow()
+
+ app.on('activate', function () {
+ // On macOS it's common to re-create a window in the app when the
+ // dock icon is clicked and there are no other windows open.
+ if (BrowserWindow.getAllWindows().length === 0) createWindow()
+ })
+})
+
+// Quit when all windows are closed, except on macOS. There, it's common
+// for applications and their menu bar to stay active until the user quits
+// explicitly with Cmd + Q.
+app.on('window-all-closed', () => {
+ if (process.platform !== 'darwin') {
+ app.quit()
+ }
+})
+
+// In this file you can include the rest of your app's specific main process
+// code. You can also put them in separate files and require them here.
diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts
new file mode 100644
index 0000000..a153669
--- /dev/null
+++ b/src/preload/index.d.ts
@@ -0,0 +1,8 @@
+import { ElectronAPI } from '@electron-toolkit/preload'
+
+declare global {
+ interface Window {
+ electron: ElectronAPI
+ api: unknown
+ }
+}
diff --git a/src/preload/index.ts b/src/preload/index.ts
new file mode 100644
index 0000000..2d18524
--- /dev/null
+++ b/src/preload/index.ts
@@ -0,0 +1,22 @@
+import { contextBridge } from 'electron'
+import { electronAPI } from '@electron-toolkit/preload'
+
+// Custom APIs for renderer
+const api = {}
+
+// Use `contextBridge` APIs to expose Electron APIs to
+// renderer only if context isolation is enabled, otherwise
+// just add to the DOM global.
+if (process.contextIsolated) {
+ try {
+ contextBridge.exposeInMainWorld('electron', electronAPI)
+ contextBridge.exposeInMainWorld('api', api)
+ } catch (error) {
+ console.error(error)
+ }
+} else {
+ // @ts-ignore (define in dts)
+ window.electron = electronAPI
+ // @ts-ignore (define in dts)
+ window.api = api
+}
diff --git a/index.html b/src/renderer/index.html
similarity index 100%
rename from index.html
rename to src/renderer/index.html
diff --git a/src/App.svelte b/src/renderer/src/App.svelte
similarity index 78%
rename from src/App.svelte
rename to src/renderer/src/App.svelte
index f75b68a..f516c93 100644
--- a/src/App.svelte
+++ b/src/renderer/src/App.svelte
@@ -1,6 +1,6 @@
@@ -20,12 +20,12 @@
- Check out SvelteKit, the official Svelte app framework powered by Vite!
+ Check out SvelteKit, the official Svelte app framework powered by Vite!
-
- Click on the Vite and Svelte logos to learn more
-
+ Click on the Vite and Svelte logos to learn more