sidebase is a modern, best-practice, batteries-included fullstack-app starter based on Nuxt 3 and TypeScript.
With this nuxt 3 starter you get production-ready frontend + backend projects while still having fun! Atinux, CEO of Nuxt said to sidebase on Twitter:
Beautiful work on sidebase!
- Use the official
nuxi
-cli to start:npx nuxi@latest init -t community/sidebase
- Go into the
nuxt-sidebase/
directorycd nuxt-sidebase
- Install the dependencies
npm i
- Start developing (with database, backend, API, ... running) at localhost:3000
npm run dev
The key features are:
- 🎒 Fullstack: Develop frontend and backend in a single TypeScript code base
- Fullstack
Vue 3
+Nuxt 3 RC.10
, - Data base models, migrations, queries and easy DB-switching via
TypeORM
, - Frontend- and Backend data-transformation via
nuxt-sidebase-parse
andzod
, - In-memory development SQL-database via
sqlite3
, - Linting via
eslint
, - Test management, Test UI, component snapshotting via
vitest
, - Component tests via
test-library/vue
, - API tests via
supertest
, - Code coverage via
c8
, - Component stories via
histoire
, - CSS utiltities via
TailwindCSS
, - CSS components via
Ant Design Vue
, - Type checking in script and template via
Volar / vue-tsc
- Fullstack
- 🏎️ Fast to code: Database, example tests, example components and example pages are all there for you to fill out
- 🐛 Fewer bugs: Strong data-validation using
zod
to validate all transferred data, fully typed API-routes, strict DB models viaTypeORM
- 😊 Easy to use: Designed to follow best practices and to be ready-to-go for development, without additional dev-dependencies like
docker
that make it hard to get started - 🚀 Ready for launch: Github Actions CI, Dockerfile, easy switch to most popular SQL-databases are all there, out of the box (get in touch if you're missing something)
To facilitate this sidebase
bootstraps a nuxt 3 project that permits developing a backend and a frontend using just Nuxt 3 with overarching TypeScript support. We want to show the world how enjoyable end-to-end typescript programming can be, displacing the myth that JS/TS-backends are no good. This starter solves a lot fo the "real-world" problems that occur after you start using Nuxt or any other framework: How to write backend tests? How to write component tests? How to calculate test coverage? How to integrate a database? How to build a docker image? ...?
If you have any problems with this project (e.g., setting it up on your PC) open an issue and we'll figure it out together with you 🎉
This is the documentation section of sidebase. It contains useful commands and guides to make your work easier and more pleasurable.
Useful Commands for development, testing and deployment:
- Develop & Debug the app:
npm i
: Install required dependenciesnpm run dev
: Start the fullstack app, including databasenpm run story
: Starthistoire
for component story based development of UI
- Linting & Formatting (
npm run lint
)npm run lint:style
: eslint for formatting & lintingnpm run lint:style -- --fix
: Autofix styles and lints where possiblenpm run lint:types
: typescript typechecking
- Testing & Code Coverage & Component Snapshots
npm run test
: Run tests once, report results and coveragenpm run test:watch
: Run tests and watch file changes, run tests for changed filesnpm run test -- -u
: Update component snapshots after components changednpm run test -- -t "some test-text"
: Run all tests withsome test-text
in theirtest(...)
description
npm run test:ui
: Run the vitest testing web UI for easier test interaction@testing-library/vue
for easy and best-practice component tests, see example here- breakpoint debugging (zero-config in VS Code)
- Open the command palette (CMD / CTRL + SHIFT + P)
- Select "Debug: JavaScript Debug Terminal"
- Run any
npm
command insideapp/
, e.g.:npm run test
- Your code editor colors should change a bit (e.g.: to orange) while executing the command, the left side should show deep execution insights
- Set breakpoints (click left of line count in editor - red dot should appear) - the debugger will automatically work and stop at them and allow you to inspect variables
- Run a command that runs the code you set breakpoints at, e.g.,
npm run test
- Building & Deploying:
npm run build
: Build the app for productionnpm run start
: Start the app in production (requiresnpm run build
beforehand)
- CSS usable without imports
- Utility & Styling: TailwindCSS 3
- Components: Ant Design Vue with component-auto-import
- slim docker ready
> docker build -t nuxt3-app . > docker run -p 3000:3000 --init --rm nuxt3-app
- Note: Docker is not required for development or deployment - for development
sqlite3
is used and will launch automatically vianpm run dev
🚀
- Note: Docker is not required for development or deployment - for development
- Miscallaneous
nvm use
: If you usenvm
, use this command to make sure that your local environment uses the correct, required node version- Pre-commit checking (husky) & fixing (lint-staged)
- github CI pipeline to linting, testing, typing checks
- nuxt-component support in tests and histoire
- debug sql database queries by setting
logging: true
in thedatabase/index.ts
: This will show you a live log of all ongoing database queries which is super helpful to debug database problems
Useful guides to get started with or use more advanced features of sidebase
.
If this is the first time you run a npm
/ node
app on your setup:
- Install the
node
version managernvm
by running:> curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
- Install the required
node
andnpm
version:# uses existing `.nvmrc`-file to install required version > nvm install
- Use the required
node
andnpm
version:# uses `.nvmrc` to use required version > nvm use # ALTERNATIVE: make node 16.14.2 your default node version (version copied from `.nvmrc`, check there for most up to date node version) > nvm alias default 16.14.2
- Install a code editor (recommended: VS Code), get it here
- Uninstall or disable the old Vue VS Code extension
Vetur
, else conflicts may arise betweenvolar
andVetur
- Install the
volar
extension to supportvue
,nuxt
andtypescript
development help - Enable "take over mode" for volar for this project.
- documented here: vuejs/language-tools#471
- for VS Code:
- Run (CMD/CTRL + SHIFT + P): Extensions: Show Built-in Extensions
- Find "TypeScript and JavaScript Language Features"
- Right click and select "disable for workspace"
- Reload the editor
- A message "Take over mode enabled" (or similar) should appear
- Go to the top of this section and execute commands (start with
npm i
to get all packages!)
If you have type-problems after running npm i
for the first time:
- Ensure you have
vetur
disabled or uninstalled (see above), - Ensure you have the builtin
typescript
extention of VS Code disabled (see above), - Reload the
vue
volar server (VS Code command: "Volar: Restart Vue Server") - Close and re-open the file you have problems with
If none of this works, file an issue (preferrably with a reproduction) here.
nuxt-sidestream-parse
to validate and deserialize data from theserver
in thefrontend
:- Define a zod-schema for the response of your endpoint, like so:
// file: ~/server/schemas/healthz.ts import { z } from '@sidestream-tech/nuxt-sidebase-parse' import { transformStringToDate } from './helpers' export const responseSchemaHealthCheck = z.object({ status: z.literal('healthy'), time: z.string().transform(transformStringToDate), nuxtAppVersion: z.string(), }) export type ResponseHealthcheck = z.infer<typeof responseSchemaHealthCheck>
- Define an endpoint that returns complex data (e.g.: date-objects), like so:
// file: ~/server/api/healthz.get.ts import { defineEventHandler } from 'h3' import type { ResponseHealthcheck } from '~/server/schemas/healthz' export default defineEventHandler((): ResponseHealthcheck => { return { status: 'healthy', time: new Date(), nuxtAppVersion: process.env.NUXT_APP_VERSION || 'unknown', } })
- Call it from the frontend, get free data validation, derserialization (e.g.: string-date is transformed to
Date
object) and typing, like so:// file: ~/pages/index.vue import { makeParser } from '@sidestream-tech/nuxt-sidebase-parse' import { responseSchemaHealthCheck } from '~/server/schemas/healthz' const transform = makeParser(responseSchemaHealthCheck) const { data } = await useFetch('/api/healthz', { transform }) console.log(data) // -> Object { status: "healthy", time: Date Thu Sep 15 2022 15:45:53 GMT+0200 (Central European Summer Time), nuxtAppVersion: "unknown" }
- That's it!
data
will be fully typed AND all data inside will be de-serialized, sotime
will be aDate
-object, and not a string, that you first need to deserialize - If an
error
is thrown, it's done using nuxtcreateError
, so it works well in frontend and on the server.data
will be null in that case. You can find zod-details about your error inerror.data
- Define a zod-schema for the response of your endpoint, like so:
- Use
nuxt-sidestream-parse
to validate data that the user has passed to your API endpoint:- Parse user data like this:
import { defineEventHandler } from 'h3' import type { CompatibilityEvent } from 'h3' import { parseBodyAs, z } from '@sidestream-tech/nuxt-sidebase-parse' export default defineEventHandler(async (event: CompatibilityEvent) => { // Parse the payload using the update schema. The parsing is important to avoid bad, incorrect or malicious data coming in const payload = await parseBodyAs(event, z.object({ requestId: z.string().uuid(), pleaseDoubleThisNumber: z.number() })) return { requestId: payload.requestId, doubledNumber: 2 * payload.pleaseDoubleThisNumber } })
- Other helpers like
parseQueryAs
,parseCookiesAs
,parseParamsAs
, ... are defined in@sidestream-tech/nuxt-sidebase-parse
. See a bigger example here
- Parse user data like this: