Skip to content

Commit b410bd9

Browse files
committed
Initialize Rust+Svelte project
1 parent 970af2e commit b410bd9

34 files changed

Lines changed: 9729 additions & 130 deletions

.gitignore

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
2+
# VS Code
3+
.vscode/
4+
15
# IntelliJ IDEA project files
26
.idea/
3-
/*.iml
7+
/*.iml
8+
9+
# macOS system files
10+
.DS_Store
11+
12+
# .env files
13+
.env
14+
.env.*
15+
!.env.example
16+
17+
# Node modules
18+
node_modules
19+
20+
# SvelteKit build files
21+
/build
22+
/.svelte-kit
23+
/package
24+
vite.config.js.timestamp-*
25+
vite.config.ts.timestamp-*

.prettierrc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@
44
"semi": false,
55
"singleQuote": true,
66
"quoteProps": "as-needed",
7-
"jsxSingleQuote": true,
87
"trailingComma": "all",
98
"bracketSpacing": true,
109
"bracketSameLine": false,
1110
"arrowParens": "always",
1211
"endOfLine": "lf",
1312
"printWidth": 120,
14-
"proseWrap": "always"
13+
"proseWrap": "always",
14+
"plugins": ["prettier-plugin-svelte"],
15+
"overrides": [
16+
{
17+
"files": "*.svelte",
18+
"options": {
19+
"parser": "svelte"
20+
}
21+
}
22+
]
1523
}
Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -23,61 +23,6 @@ So, let's just focus on the boilerplate and the tooling I'll need to read/write+
2323
display it extremely fast.
2424
No other planning is needed, only what's necessary for the above.
2525

26-
### Planner Response
27-
28-
I'll research the latest tooling for Rust, Tauri, and Svelte to give you comprehensive recommendations. Let me search for current best practices and versions.
29-
30-
* Searched web for Rust linting tools 2025 clippy rustfmt best practices*
31-
* Searched web for Tauri 2.0 latest version 2025 setup requirements*
32-
* Searched web for Svelte 5 latest version 2025 TypeScript setup*
33-
* Searched web for Rust testing framework 2025 cargo test coverage*
34-
* Searched web for Svelte testing vitest playwright 2025 best practices*
35-
* Searched web for Rust security audit cargo-audit cargo-deny 2025*
36-
37-
### Planner Response
38-
39-
Let me search for the specific latest versions of these tools:
40-
41-
* Searched web for Rust 1.83 latest stable version December 2025*
42-
* Searched web for Tauri 2.1 latest version December 2025*
43-
* Searched web for Svelte 5 latest version December 2025*
44-
* Searched web for Rust file system watcher notify crate fast directory watching 2025*
45-
* Searched web for eslint svelte 5 plugin 2025 typescript*
46-
* Searched web for prettier svelte 5 plugin 2025*
47-
* Searched web for vitest latest version December 2025*
48-
* Searched web for playwright latest version December 2025*
49-
* Searched web for SvelteKit latest version December 2025*
50-
* Searched web for cargo-nextest latest version December 2025*
51-
* Searched web for cargo-llvm-cov latest version 2025*
52-
* Searched web for Rust complexity analyzer mccoybe cognitive complexity 2025*
53-
54-
### Planner Response
55-
56-
Now I have all the information needed. Let me compile this comprehensive response for you.
57-
58-
---
59-
60-
# Rust + Tauri + Svelte Tooling Guide for Type Safety & Quality (December 2025)
61-
62-
Based on my research, here's the complete tooling stack equivalent to your Go+TS+React quality controls, mapped to the Rust+Tauri+Svelte ecosystem.
63-
64-
## 🔧 Tooling Equivalence Map
65-
66-
| Your Go/TS Tool | Purpose | Rust/Svelte Equivalent |
67-
|-----------------------|--------------------------|--------------------------------------------------|
68-
| `gofmt` | Code formatting | **rustfmt** (built-in) |
69-
| `govulncheck` | Security vulnerabilities | **cargo-audit** + **cargo-deny** |
70-
| `staticcheck` | Static analysis | **Clippy** (built-in) |
71-
| `ineffassign` | Unused assignments | **Clippy** lints |
72-
| `misspell` | Spelling in code | **typos** (CLI tool) |
73-
| `gocyclo` (max 15) | Cyclomatic complexity | **Clippy** cognitive complexity threshold |
74-
| `nilaway` | Null safety | Rust's **Option/Result** (compile-time!) |
75-
| `Prettier` | JS/TS formatting | **prettier-plugin-svelte** |
76-
| `ESLint` | JS/TS linting | **eslint-plugin-svelte** + **typescript-eslint** |
77-
| `Vitest` | Unit/component testing | **Vitest** (same!) |
78-
| `Playwright` | E2E testing | **Playwright** (same!) |
79-
| `Chromatic Storybook` | Component visual testing | **Storybook** + **vitest-browser-svelte** |
80-
8126
---
8227

8328
## 🦀 Rust Backend Tooling

e2e/smoke.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { test, expect } from '@playwright/test'
2+
3+
test('app loads successfully', async ({ page }) => {
4+
await page.goto('/')
5+
await expect(page.locator('body')).toBeVisible()
6+
})

eslint.config.js

Lines changed: 26 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,26 @@
11
import js from '@eslint/js'
2-
import globals from 'globals'
3-
import reactHooks from 'eslint-plugin-react-hooks'
4-
import reactRefresh from 'eslint-plugin-react-refresh'
5-
import react from 'eslint-plugin-react'
6-
import reactX from 'eslint-plugin-react-x'
7-
import reactDom from 'eslint-plugin-react-dom'
82
import prettier from 'eslint-plugin-prettier'
93
import prettierConfig from 'eslint-config-prettier'
104
import tseslint from 'typescript-eslint'
11-
import importPlugin from 'eslint-plugin-import'
5+
import svelte from 'eslint-plugin-svelte'
6+
import svelteParser from 'svelte-eslint-parser'
7+
import globals from 'globals'
128

13-
export default [
9+
export default tseslint.config(
1410
{
15-
ignores: ['dist'],
11+
ignores: ['dist', 'build', '.svelte-kit', 'node_modules', 'src-tauri/target'],
1612
},
1713
js.configs.recommended,
1814
prettierConfig,
19-
...tseslint.configs.strictTypeChecked.map(config => ({
15+
...tseslint.configs.strictTypeChecked.map((config) => ({
2016
...config,
21-
files: ['**/*.{ts,tsx}'],
17+
files: ['**/*.{ts,tsx,svelte}'],
2218
})),
23-
{
24-
...reactX.configs['recommended-typescript'],
25-
files: ['**/*.{ts,tsx}'],
26-
},
27-
{
28-
...reactDom.configs.recommended,
29-
files: ['**/*.{ts,tsx}'],
30-
},
19+
...svelte.configs['flat/recommended'],
3120
{
3221
files: ['**/*.{ts,tsx}'],
3322
plugins: {
3423
'@typescript-eslint': tseslint.plugin,
35-
react,
36-
'react-hooks': reactHooks,
37-
'react-refresh': reactRefresh,
38-
import: importPlugin,
3924
prettier,
4025
},
4126
languageOptions: {
@@ -47,33 +32,11 @@ export default [
4732
...globals.es2021,
4833
},
4934
parserOptions: {
50-
ecmaFeatures: {
51-
jsx: true,
52-
},
53-
project: ['./tsconfig.node.json', './tsconfig.app.json', './tsconfig.e2e.json'],
35+
projectService: true,
5436
tsconfigRootDir: import.meta.dirname,
5537
},
5638
},
57-
settings: {
58-
react: {
59-
version: 'detect',
60-
},
61-
},
6239
rules: {
63-
...reactHooks.configs.recommended.rules,
64-
'react/react-in-jsx-scope': 'off',
65-
'react/jsx-key': 'error',
66-
'react/jsx-no-duplicate-props': 'error',
67-
'react/jsx-no-undef': 'error',
68-
'react/jsx-uses-react': 'off',
69-
'react/jsx-uses-vars': 'error',
70-
'react/no-array-index-key': 'warn',
71-
'react/no-danger': 'warn',
72-
'react/no-deprecated': 'error',
73-
'react/no-direct-mutation-state': 'error',
74-
'react/no-unknown-property': 'error',
75-
'react/prop-types': 'off',
76-
'react-dom/no-dangerously-set-innerhtml': 'warn',
7740
'prettier/prettier': 'error',
7841
'@typescript-eslint/no-unused-vars': 'error',
7942
'@typescript-eslint/no-unsafe-assignment': 'error',
@@ -86,25 +49,6 @@ export default [
8649
'@typescript-eslint/require-await': 'error',
8750
'@typescript-eslint/no-explicit-any': 'error',
8851
'no-console': 'warn',
89-
// Prettier handles "quotes", "jsx-quotes", "indent", "semi", and "comma-dangle".
90-
'import/order': [
91-
'error',
92-
{
93-
groups: [
94-
'builtin',
95-
'external',
96-
'internal',
97-
'parent',
98-
'sibling',
99-
'index',
100-
],
101-
'newlines-between': 'always',
102-
alphabetize: {
103-
order: 'asc',
104-
caseInsensitive: true,
105-
},
106-
},
107-
],
10852
complexity: [
10953
'warn',
11054
{
@@ -114,16 +58,26 @@ export default [
11458
},
11559
},
11660
{
117-
files: ['scripts/**/*.mjs'],
61+
files: ['**/*.svelte'],
11862
languageOptions: {
119-
globals: {
120-
...globals.node,
63+
parser: svelteParser,
64+
parserOptions: {
65+
parser: tseslint.parser,
66+
projectService: true,
67+
tsconfigRootDir: import.meta.dirname,
68+
extraFileExtensions: ['.svelte'],
12169
},
122-
ecmaVersion: 'latest',
123-
sourceType: 'module',
12470
},
12571
rules: {
126-
'no-console': 'off', // Scripts can use console
72+
'prettier/prettier': 'error',
73+
'@typescript-eslint/no-unused-vars': 'error',
74+
'no-console': 'warn',
75+
complexity: [
76+
'warn',
77+
{
78+
max: 15,
79+
},
80+
],
12781
},
12882
},
129-
]
83+
)

package.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "tauri-app",
3+
"version": "0.1.0",
4+
"description": "",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite dev",
8+
"build": "vite build",
9+
"preview": "vite preview",
10+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
11+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
12+
"tauri": "tauri",
13+
"lint": "eslint .",
14+
"lint:fix": "eslint . --fix",
15+
"format": "prettier --write .",
16+
"format:check": "prettier --check .",
17+
"test": "vitest run",
18+
"test:watch": "vitest",
19+
"test:e2e": "playwright test"
20+
},
21+
"license": "MIT",
22+
"dependencies": {
23+
"@tauri-apps/api": "^2",
24+
"@tauri-apps/plugin-opener": "^2"
25+
},
26+
"devDependencies": {
27+
"@eslint/js": "^9.39.2",
28+
"@playwright/test": "^1.57.0",
29+
"@sveltejs/adapter-static": "^3.0.6",
30+
"@sveltejs/kit": "^2.9.0",
31+
"@sveltejs/vite-plugin-svelte": "^5.0.0",
32+
"@tauri-apps/cli": "^2",
33+
"@testing-library/svelte": "^5.3.1",
34+
"@types/node": "^25.0.3",
35+
"eslint": "^9.39.2",
36+
"eslint-config-prettier": "^10.1.8",
37+
"eslint-plugin-prettier": "^5.5.4",
38+
"eslint-plugin-svelte": "^3.13.1",
39+
"globals": "^16.5.0",
40+
"jsdom": "^27.3.0",
41+
"prettier": "^3.7.4",
42+
"prettier-plugin-svelte": "^3.4.1",
43+
"svelte": "^5.0.0",
44+
"svelte-check": "^4.0.0",
45+
"svelte-eslint-parser": "^1.4.1",
46+
"typescript": "~5.6.2",
47+
"typescript-eslint": "^8.50.1",
48+
"vite": "^6.0.3",
49+
"vitest": "^4.0.16"
50+
}
51+
}

playwright.config.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
3+
export default defineConfig({
4+
testDir: './e2e',
5+
fullyParallel: true,
6+
forbidOnly: !!process.env.CI,
7+
retries: process.env.CI ? 2 : 0,
8+
workers: process.env.CI ? 1 : undefined,
9+
reporter: 'html',
10+
use: {
11+
baseURL: 'http://localhost:1420',
12+
trace: 'on-first-retry',
13+
},
14+
projects: [
15+
{
16+
name: 'chromium',
17+
use: { ...devices['Desktop Chrome'] },
18+
},
19+
{
20+
name: 'webkit',
21+
use: { ...devices['Desktop Safari'] },
22+
},
23+
],
24+
webServer: {
25+
command: 'pnpm tauri dev',
26+
url: 'http://localhost:1420',
27+
reuseExistingServer: !process.env.CI,
28+
timeout: 120 * 1000,
29+
},
30+
})

0 commit comments

Comments
 (0)