A fullstack typescript offline-first PWA template repo, ready to use
Tip
Quick start: Just click the Use this template button to create a new repository with this template.
Warning
Don't forget to add an .env file:
You can rename the .env.example file into .env for a minimal starting point that will be enough for the app to run
A typescript React application, with
- Vitest
- Vite
- SQLite (vlcn.io CRDTs) + useQuery hook for reactive queries
- Tanstack Query + useQuery hook for server<->client type-safety
A typescript Fastify server, with
- SQLite (vlcn.io CRDTs)
- esbuild
- Vitest
- oauth through 3rd party providers
A typescript service worker, with
- esbuild
- Hot Module Reloading
A workspace, with
- pnpm (package manager / script runner)
- eslint w/ type-aware linting (code quality)
- prettier (code formatting)
- knip (dead code elimination)
- turbo (monorepo manager / script cache)
- valibot (data validation)
- ts-reset (better typescript defaults)
- cspell (code spell-checking)
- github actions (CI/CD) with auto-releases
- a
scriptfolder for build-time shared code (node only, for CI, vite plugins, ...) - a
sharedfolder for run-time shared code (all environments, for client, server, service worker, ...)
To get started with this project, click on Use this template on GitHub (or clone the repository, but you will be missing the github config) and install the dependencies with pnpm:
pnpm installTo start the development server, run:
pnpm devIn dev mode, all requests go through Vite's dev server, and all /api requests are forwarded to the Fastify server.
To test the project, run:
pnpm testTo serve the production build, run:
pnpm serveIn production mode, all requests go through the Fastify server.
To build the project for production, run:
pnpm buildThe assets necessary for running the project after it has been built are:
/dist.env/node_modules(because not all imports are bundled)/db(though it will be generated if it doesn't exist)
Tip
Easy deployment:
The bundle.tar.xz release artifact uploaded to GitHub contains
- the
/distfolder, - the
package.jsonfile, - and the
pnpm-lock.yamlfile.
After unpacking,
- provide your
.envfile, - install the runtime dependencies (
pnpm install --frozen-lockfile --prod)
And the app is ready to run. This allows you to use the GitHub webhooks to call your server and easily re-deploy on every version change.
pnpm format # prettier check
pnpm format:fix # prettier fix
pnpm lint # eslint check
pnpm lint:fix # eslint fix
pnpm tsc # typescript check
pnpm knip # check for unused code
pnpm spell # check for spelling errors
pnpm clear # clear cache (turbo, vite, pnpm, esbuild, ...)
pnpm analyze # bundle size analysis- database: figure out migrations story
-
maybe through drizzle?- not compatible with sqlite wasm (drizzle-team/drizzle-orm#193, drizzle-team/drizzle-orm#243)
- Manual migrations seem ok
- do we want down migrations?
- should migrations be separate from source code and be fetched? Or part of the source and the client simply cannot sync if the app is not up to date?
- how do we know which migrations to run? (on the server, and on the client)
-
- cleanup bento:
- make the default page nicer looking
- cleanup DB demo component
- docs: write docs w/ fumadocs on root-docs repo
- While working on CSS, ESLint can lose the types of
classesobjects. This might have been fixed by adding a tcm process to thedevcommand, but it needs to be tested.