Skip to content

mulekick/vittel

Repository files navigation

Vittel

Full-stack monorepo starter kit for service oriented typescript apps

Table of contents

  1. Design goals
  2. Packages types
  3. Prerequisites
  4. Scaffold your project
  5. Project structure
  6. CI/CD pipeline
  7. Dependencies management
  8. Features
  9. Footnotes

Design goals

  • Write node.js services that follow the 3 tier architecture pattern.
  • Write node.js services that follow the best practices for production apps.
  • Configure a tooling suite for the entire monorepo (settings are overriden at package level).
  • Provide features scaling capabilities through code sharing and type driven development.
  • Provide capabilities for unit testing with jest and end-to-end testing with puppeteer.
  • Provide capabilities for services containerization with Dockerfile and docker buildx.
  • Configure a fully local CI/CD pipeline orchestrated by nx for quick iterations and secure deliveries.

Packages types

  • The monorepo manages interdependent packages to implement a full service oriented app.
  • Different types of packages can be created for complementary purposes :
  1. Npm packages :
    • Code that has to be shared / reused across the app.
    • CI/CD pipeline builds the package into an npm module for use in other packages.
    • @vittel/types and @vittel/utils are included as templates.
  2. Node.js packages :
    • Code for a server app that executes in a node.js environment.
    • Supports different configs for development and production mode.
    • CI/CD pipeline builds the package into a docker image ready for deployment.
    • @vittel/backend is included as a template.
  3. Frontend packages :
    • Code for a browser app that is statically served by another service (node.js or external).
    • Supports different configs for development and production mode.
    • CI/CD pipeline builds the package and publishes it to a static serving location.
    • @vittel/frontend is included as a template.
  4. E2e packages :
    • Code for end-to-end tests, not part of the app itself.
    • End-to-end tests support browser automation with puppeteer and jest.
    • CI/CD pipeline will error (thus alert) should any of those tests fail.
    • @vittel/e2e is included as a template.
  5. External packages :
    • Non-typescript services required for app operation or e2e tests (databases, proxies, message queues, etc).
    • Such services usually contain only configuration assets and optionally a Dockerfile.
    • CI/CD pipeline builds the package into a docker image if needed.

Note : the npm types package should always be present to allow centralized management of types across the monorepo.

Prerequisites

software recommended version
Linux Debian 12 bookworm
GNU Bash 5.2.15
Node.js 22.15.0
NPM 10.9.2
Docker 28.3.3
docker-buildx-plugin 0.26.1
Puppeteer browser google chrome / puppeteer defaults

Scaffold your project

  • Use the following commands to scaffold a new project :
# clone the repository using degit
npx degit https://github.com/mulekick/vittel.git my-vittel-project

# cd into your project
cd my-vittel-project

# initialize monorepo and install dependencies
npm run deps:install

# run the initial build to make types available
npx lerna run build

Project structure

my-vittel-project/
β”œβ”€β”€ .nx/               # nx cache
β”œβ”€β”€ packages/          # workspace packages
β”‚   β”œβ”€β”€ backend/       # sample server app
β”‚   β”œβ”€β”€ frontend/      # sample browser app
β”‚   β”œβ”€β”€ types/         # shared types, parsers and enums
β”‚   β”œβ”€β”€ utils/         # shared utilities
β”‚   └── e2e/           # end to end tests
β”œβ”€β”€ babel.config.js    # global babel config (transpiles code for jest)
β”œβ”€β”€ docker.registry    # registry for new docker images
β”œβ”€β”€ eslint.config.js   # global eslint config
β”œβ”€β”€ jest.config.js     # global jest config
β”œβ”€β”€ lerna.json         # lerna config file
β”œβ”€β”€ nx.json            # nx targets definition and orchestration
β”œβ”€β”€ package-lock.json  # global npm lockfile (important)
β”œβ”€β”€ package.json       # monorepo dependencies and workspaces
β”œβ”€β”€ tsconfig.json      # global tsconfig
└── typedoc.config.js  # global typedoc config
  • Individual packages structures are detailed in their respective README pages.

CI/CD pipeline

  • Available CI / CD tasks are executed using lerna and depend on packages types :
name npm node frontend e2e external description
list X X X X Lists known types for the package
dev X X X Starts the package in dev mode
typecheck X X X X Validates the package types against tsconfig
lint X X X X Lints the package code against eslint.config.js
test X X X X Runs jest tests for the package
types:build X Creates *.d.ts files for the package types
build X X X X Creates the package build
publish X X Publishes the package build depending on its type
docker:lockfile X Copies global package-lock.json to the package directory
docker:build X X X Bundles the package and its dependencies into a docker image
docker:push X X Pushes the docker image into the configured docker registry
docs:build X X X Builds typedoc documentation for the package
  • Tasks are orchestrated as targets according to the nx configuration.
  • Type npx lerna run <task> to execute the pipeline up to the specified target.
  • Depending on the use case, other tasks can be added and nx config must be updated accordingly.
  • Required tasks for external packages can vary depending on the use case.

Dependencies management

  • The recommended way of updating dependencies for the monorepo or for individual packages is to :
    • Update the relevant package.json files.
    • Run npm run deps:install so as to preserve the consistency of package-lock.json (very important).
  • The npm dependency graph sometime breaks which causes the docker:build target to error (a npm message will show in the docker logs).
  • If that happens, run the following commands :
# delete lockfile, node_modules folder and nx cache
npm run deps:reset

# reinstall dependencies and clean rebuild graph and lockfile
npm run deps:install

Features

Static typing and linting

module usage
typescript Static typing for the entire monorepo.
eslint Static code analysis for the entire monorepo.
tsx On-demand compilation for node.js packages.
zod Server-side data parsing and validation at runtime.
typedoc Build package documentation from types and comments.

DX

module usage
dotenv Load environment variables from config files.
nodemon Auto-restart on file changes during node.js package development.
vite HMR + auto-reload on file change during frontend apps development.

Building

module usage
npm Create packages for code reusability across the entire workspace.
esbuild Create builds for npm and node.js packages.
vite Create builds for frontend packages.
docker buildx Create docker images for node.js and external packages.

Testing

module usage
jest Run unit tests for npm and node.js packages.
testing-library Run unit tests for frontend packages components.
puppeteer Run end to end tests through browser automation.
jest-puppeteer Add jest matchers support for end-to-end tests.

CI/CD

module usage
nx Orchestrate the pipeline across all packages, manage tasks execution cache.
lerna Manage the monorepo and run the CI/CD pipeline.

Footnotes

  • This project is at its fourth major iteration (it started with plain javascript, then react, then typescript, and now a full blown typescript-based monorepo).

About

Typescript monorepo starter kit πŸš€

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors