├── .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 | --------------------------------------------------------------------------------