sidebase
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!
Quick start
- Use the official
nuxi
-cli to start:
npx nuxi@latest init -t community/sidebase
- Go into the
nuxt-sidebase/
directory
cd nuxt-sidebase
- Install the dependencies
npm i
- Start developing (with database, backend, API, ... running) at localhost:3000
npm run dev
Features
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-parse
and zod
, - 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
- 🏎️ 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 via TypeORM
- 😊 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 🎉
Documentation
This is the documentation section of sidebase. It contains useful commands and guides to make your work easier and more pleasurable.
Commands
Useful Commands for development, testing and deployment:
Guides
Useful guides to get started with or use more advanced features of sidebase
.
First time node and npm setup
If this is the first time you run a npm
/ node
app on your setup:
- Install the
node
version manager nvm
by running:
> curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
- Install the required
node
and npm
version:
> nvm install
- Use the required
node
and npm
version:
> nvm use
> 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 between volar
and Vetur
- Install the
volar
extension to support vue
, nuxt
and typescript
development help
- Enable "take over mode" for volar for this project.
- documented here: https://github.com/johnsoncodehk/volar/discussions/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-parse
nuxt-parse
to validate and deserialize data from the server
in the frontend
:
- Define a zod-schema for the response of your endpoint, like so:
import { z } from '@sidebase/nuxt-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:
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:
import { makeParser } from '@sidebase/nuxt-parse'
import { responseSchemaHealthCheck } from '~/server/schemas/healthz'
const transform = makeParser(responseSchemaHealthCheck)
const { data } = await useFetch('/api/healthz', { transform })
console.log(data)
- That's it!
data
will be fully typed AND all data inside will be de-serialized, so time
will be a Date
-object, and not a string, that you first need to deserialize - If an
error
is thrown, it's done using nuxt createError
, 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 in error.data
- Use
nuxt-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 '@sidebase/nuxt-parse'
export default defineEventHandler(async (event: CompatibilityEvent) => {
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 @sidebase/nuxt-parse
. See a bigger example here
License
MIT