├── .gitignore
├── index.html
├── license
├── package.json
├── readme.md
├── src
├── app
│ ├── app.tsx
│ └── index.tsx
├── entities
│ └── .gitkeep
├── features
│ └── .gitkeep
├── index.ts
├── pages
│ └── .gitkeep
├── shared
│ └── .gitkeep
├── vite-env.d.ts
└── widgets
│ └── .gitkeep
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | ### Jetbrains IDE custom template
2 |
3 | # Every plugin and inner IDE tool creates its own XML config, so
4 | # it's easier to ignore whole .idea directory
5 | .idea
6 |
7 | ### Node.js custom template
8 |
9 | # Lockfiles
10 | package-lock.json
11 | yarn.lock
12 |
13 | ### VisualStudioCode template
14 | .vscode/*
15 | !.vscode/settings.json
16 | !.vscode/tasks.json
17 | !.vscode/launch.json
18 | !.vscode/extensions.json
19 | *.code-workspace
20 |
21 | # Local History for Visual Studio Code
22 | .history/
23 |
24 | ### Linux template
25 | *~
26 |
27 | # temporary files which can be created if a process still has a handle open of a deleted file
28 | .fuse_hidden*
29 |
30 | # KDE directory preferences
31 | .directory
32 |
33 | # Linux trash folder which might appear on any partition or disk
34 | .Trash-*
35 |
36 | # .nfs files are created when an open file is removed but is still being accessed
37 | .nfs*
38 |
39 | ### Node template
40 | # Logs
41 | logs
42 | *.log
43 | npm-debug.log*
44 | yarn-debug.log*
45 | yarn-error.log*
46 | lerna-debug.log*
47 |
48 | # Diagnostic reports (https://nodejs.org/api/report.html)
49 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
50 |
51 | # Runtime data
52 | pids
53 | *.pid
54 | *.seed
55 | *.pid.lock
56 |
57 | # Directory for instrumented libs generated by jscoverage/JSCover
58 | lib-cov
59 |
60 | # Coverage directory used by tools like istanbul
61 | coverage
62 | *.lcov
63 |
64 | # nyc test coverage
65 | .nyc_output
66 |
67 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
68 | .grunt
69 |
70 | # Bower dependency directory (https://bower.io/)
71 | bower_components
72 |
73 | # node-waf configuration
74 | .lock-wscript
75 |
76 | # Compiled binary addons (https://nodejs.org/api/addons.html)
77 | build/Release
78 |
79 | # Dependency directories
80 | node_modules/
81 | jspm_packages/
82 |
83 | # Snowpack dependency directory (https://snowpack.dev/)
84 | web_modules/
85 |
86 | # TypeScript cache
87 | *.tsbuildinfo
88 |
89 | # Optional npm cache directory
90 | .npm
91 |
92 | # Optional eslint cache
93 | .eslintcache
94 |
95 | # Microbundle cache
96 | .rpt2_cache/
97 | .rts2_cache_cjs/
98 | .rts2_cache_es/
99 | .rts2_cache_umd/
100 |
101 | # Optional REPL history
102 | .node_repl_history
103 |
104 | # Output of 'npm pack'
105 | *.tgz
106 |
107 | # Yarn Integrity file
108 | .yarn-integrity
109 |
110 | # dotenv environment variables file
111 | .env
112 | .env.test
113 |
114 | # parcel-bundler cache (https://parceljs.org/)
115 | .cache
116 | .parcel-cache
117 |
118 | # Next.js build output
119 | .next
120 | out
121 |
122 | # Nuxt.js build / generate output
123 | .nuxt
124 | dist
125 |
126 | # Gatsby files
127 | .cache/
128 | # Comment in the public line in if your project uses Gatsby and not Next.js
129 | # https://nextjs.org/blog/next-9-1#public-directory-support
130 | # public
131 |
132 | # vuepress build output
133 | .vuepress/dist
134 |
135 | # Serverless directories
136 | .serverless/
137 |
138 | # FuseBox cache
139 | .fusebox/
140 |
141 | # DynamoDB Local files
142 | .dynamodb/
143 |
144 | # TernJS port file
145 | .tern-port
146 |
147 | # Stores VSCode versions used for testing VSCode extensions
148 | .vscode-test
149 |
150 | # yarn v2
151 | .yarn/cache
152 | .yarn/unplugged
153 | .yarn/build-state.yml
154 | .yarn/install-state.gz
155 | .pnp.*
156 |
157 | ### Vim template
158 | # Swap
159 | [._]*.s[a-v][a-z]
160 | !*.svg # comment out if you don't need vector files
161 | [._]*.sw[a-p]
162 | [._]s[a-rt-v][a-z]
163 | [._]ss[a-gi-z]
164 | [._]sw[a-p]
165 |
166 | # Session
167 | Session.vim
168 | Sessionx.vim
169 |
170 | # Temporary
171 | .netrwhist
172 | *~
173 | # Auto-generated tag files
174 | tags
175 | # Persistent undo
176 | [._]*.un~
177 |
178 | ### Windows template
179 | # Windows thumbnail cache files
180 | Thumbs.db
181 | Thumbs.db:encryptable
182 | ehthumbs.db
183 | ehthumbs_vista.db
184 |
185 | # Dump file
186 | *.stackdump
187 |
188 | # Folder config file
189 | [Dd]esktop.ini
190 |
191 | # Recycle Bin used on file shares
192 | $RECYCLE.BIN/
193 |
194 | # Windows Installer files
195 | *.cab
196 | *.msi
197 | *.msix
198 | *.msm
199 | *.msp
200 |
201 | # Windows shortcuts
202 | *.lnk
203 |
204 | ### macOS template
205 | # General
206 | .DS_Store
207 | .AppleDouble
208 | .LSOverride
209 |
210 | # Icon must end with two \r
211 | Icon
212 |
213 | # Thumbnails
214 | ._*
215 |
216 | # Files that might appear in the root of a volume
217 | .DocumentRevisions-V100
218 | .fseventsd
219 | .Spotlight-V100
220 | .TemporaryItems
221 | .Trashes
222 | .VolumeIcon.icns
223 | .com.apple.timemachine.donotpresent
224 |
225 | # Directories potentially created on remote AFP share
226 | .AppleDB
227 | .AppleDesktop
228 | Network Trash Folder
229 | Temporary Items
230 | .apdisk
231 |
232 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | FSD TS React Vite App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/license:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Anton Medvedev
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "type": "module",
4 | "scripts": {
5 | "dev": "vite",
6 | "build": "tsc && vite build",
7 | "preview": "vite preview"
8 | },
9 | "dependencies": {
10 | "react": "^18.3.1",
11 | "react-dom": "^18.3.1"
12 | },
13 | "devDependencies": {
14 | "@types/react": "^18.3.2",
15 | "@types/react-dom": "^18.3.0",
16 | "@types/node": "^20.12.11",
17 | "@vitejs/plugin-react": "^4.2.1",
18 | "pkg-dir": "^8.0.0",
19 | "typescript": "^5.4.5",
20 | "vite": "^5.2.11"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # FSD + TS + React + Vite project template
2 |
3 | [![Feature-Sliced Design][shields-fsd-image]](https://feature-sliced.design/)
4 |
5 | Based on official [Vite React Typescript template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts), but slightly changed to match [Feature-Sliced architectural methodology](https://feature-sliced.design/). Here's a list of differences
6 |
7 | - Clean and empty [`app root`](./src/app/)
8 | - Directories for minimal set of FSD slices
9 | - `src/` path alias for absolute import
10 | - Advanced [`.gitignore`](./.gitignore)
11 |
12 | [shields-fsd-image]: https://img.shields.io/badge/Feature--Sliced-Design-FFFFFF?logoWidth=24&style=flat-square&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTMuNS41aDE3djJoLTE3di0yWm0wIDNoMTd2MmgtMTd2LTJabTAgM2g4djJoLTh2LTJabTAgM2gxN3YyaC0xN3YtMlptMCAzaDE3djJoLTE3di0yWm0wIDNoOHYyaC04di0yWm0wIDNoOHYyaC04di0yWm0wIDNoOHYyaC04di0yWiIvPjwvc3ZnPg==
13 |
--------------------------------------------------------------------------------
/src/app/app.tsx:
--------------------------------------------------------------------------------
1 | import React, { FunctionComponent } from 'react'
2 |
3 | export const App: FunctionComponent = () => (
4 |
5 | App
6 |
7 | )
8 |
--------------------------------------------------------------------------------
/src/app/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { createRoot } from 'react-dom/client'
3 |
4 | import { App } from './app'
5 |
6 | const reactRoot = createRoot(
7 | document.getElementById('root')!,
8 | )
9 |
10 | reactRoot.render(
11 |
12 |
13 |
14 | )
15 |
--------------------------------------------------------------------------------
/src/entities/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unordinarity/fsd-template-ts-react-vite/ff035ab2501316d85eb04ac4e9b1a2d373cb118f/src/entities/.gitkeep
--------------------------------------------------------------------------------
/src/features/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unordinarity/fsd-template-ts-react-vite/ff035ab2501316d85eb04ac4e9b1a2d373cb118f/src/features/.gitkeep
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import './app'
2 |
--------------------------------------------------------------------------------
/src/pages/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unordinarity/fsd-template-ts-react-vite/ff035ab2501316d85eb04ac4e9b1a2d373cb118f/src/pages/.gitkeep
--------------------------------------------------------------------------------
/src/shared/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unordinarity/fsd-template-ts-react-vite/ff035ab2501316d85eb04ac4e9b1a2d373cb118f/src/shared/.gitkeep
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/widgets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unordinarity/fsd-template-ts-react-vite/ff035ab2501316d85eb04ac4e9b1a2d373cb118f/src/widgets/.gitkeep
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": false,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx",
18 | "baseUrl": ".",
19 | "paths": {
20 | "src/*": ["src/*"]
21 | }
22 | },
23 | "include": [
24 | "./src"
25 | ],
26 | "references": [{ "path": "./tsconfig.node.json"}]
27 | }
28 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": true,
4 | "composite": true,
5 | "module": "esnext",
6 | "moduleResolution": "node"
7 | },
8 | "include": [
9 | "vite.config.ts"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | import path from 'node:path'
5 | import { packageDirectorySync } from 'pkg-dir'
6 |
7 | const packageRoot = packageDirectorySync()
8 |
9 | // https://vitejs.dev/config/
10 | export default defineConfig({
11 | plugins: [react()],
12 | resolve: {
13 | alias: {
14 | 'src': path.resolve(packageRoot, './src'),
15 | },
16 | },
17 | })
18 |
--------------------------------------------------------------------------------