Monorepo
Prerequisites
Personal experience
Depending on the kind of contribution you’re interested in, the following experience is recommended:
- Deep experience with TypeScript (incl. type-level programming)
- Experience with TypeScript monorepo setups
- Experience with distributed systems
- Experience with Effect (or willingness to learn)
Recommended tooling: Use Nix + direnv for a consistent development setup
To make development as easy and consistent across systems and platforms, this project uses Nix to manage “system dependencies” such as Node.js, Bun etc. You can either use Direnv setup (recommended) to automatically load the Nix env or manually use the Nix env (e.g. via nix develop --command pnpm install
).
Manual setup
You’ll need to have a recent version the following tools installed:
- Node.js
- Bun
- pnpm
Initial setup
git clone git@github.com:livestorejs/livestore.gitcd livestore# Load environment variables (including Nix dependencies)direnv allow# Install dependenciespnpm install# Build the projectpnpm build
General notes
- TypeScript
- LiveStore tries to follow the strictest TypeScript rules possible to ensure type safety and avoid subtle bugs.
- LiveStore also makes heavy use of TypeScript project references.
- LiveStore tries to follow the strictest TypeScript rules possible to ensure type safety and avoid subtle bugs.
- Package management
- This project uses pnpm to manage the workspace.
- LiveStore is primarily developed in VSCode/Cursor.
- Testing
- LiveStore uses Vitest for most tests and Playwright for browser tests.
Notable used tools / technologies
Environment variables
The .envrc
file contains all necessary environment variables for the project. You can create a .envrc.local
file to override or add variables for your local setup. You’ll need to run direnv allow
to load the environment variables.
VSCode tasks
- This project is primarily developed in VSCode and makes use of tasks to run commands.
- Common tasks are:
dev:ts
to run the TypeScript compiler in watch mode for the entire monorepopnpm:install
to install all dependencies (e.g. when changing apackage.json
)
Examples
- Once you’ve set up the monorepo locally, you’ll notice both the
src
andstandalone
directories in/examples
. - The
/examples/standalone
directory is meant as a starting point for app developers evaluating LiveStore and looking for a ready-to-run example app. - The
/examples/src
directory is meant for LiveStore maintainers and to run as part of the LiveStore monorepo. Compared to/examples/standalone
it makes use of local linking features such aworkspace:*
, TypeScriptreferences
etc. - Both directories are kept in sync via
/examples/patches
and/scripts/generate-examples.ts
. Usually it’s recommended to work in/examples/src
and generate the/examples/standalone
version viapnpm -w generate:examples:standalone
.
Making changes to examples
- Make your desired changes in
/examples/src
. (You might also need to update some of the patches in/examples/patches
.) - Run
pnpm generate:examples:standalone
to generate the/examples/standalone
version - Check whether the changes in
/examples/standalone
are what you expected. - Commit your changes in both
/examples/src
and/examples/standalone
(and possibly/examples/patches
). Note on GitHub, changes toexamples/standalone
are hidden by default.
OpenTelemetry setup
As a local OpenTelemetry setup, we recommend the docker-otel-lgtm setup.
Add the following to your .envrc.local
file:
export VITE_GRAFANA_ENDPOINT="http://localhost:30003"export GRAFANA_ENDPOINT="http://localhost:30003"export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"export VITE_OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
TypeScript
- Each package has its own
tsconfig.json
file which extends the roottsconfig.base.json
. - This project makes heavy use of TypeScript project references.
Package management
- This project uses pnpm to manage the workspace.
- We’re using the
workspace:*
protocol to link packages together. - We should try to keep dependencies to an absolute minimum and only add them if we absolutely need them.
- We also need to manually add peer dependencies for each package.
- We should try to avoid duplicate dependencies across the monorepo as much as possible as duplicate dependencies can lead to a lot of issues and pain.
- We’re also using the
resolutions
field in the rootpackage.json
to force some packages to be the same across the monorepo (ideally not needed but for some packages it’s necessary currently).
- We’re also using the
- We’re using syncpack to help maintain consistent dependency versions across the monorepo.
- See
syncpack.config.mjs
for the configuration. - Common commands:
bunx syncpack format
to format thepackage.json
filesbunx syncpack lint
to check all version rangesbunx syncpack fix-mismatches
to adjust versions acrosspackage.json
files (check before withlint
)bunx syncpack update
to update packages across the monorepo to the latest versions
- See
Notes on external dependencies
LiveStore tries to use as few external dependencies as possible. Given LiveStore is built on top of Effect, which can be considered a standard library for TypeScript, it should handle most use cases.
Notes on some packages
The following packages need to be updated with extra care:
react
/react-dom
as we need to move in lockstep with Expo / React Native (currently pinned to 19.0.0)effect
(currently pinned to 3.14.8)
Effect
- LiveStore makes heavy use of the Effect library and ecosystem throughout the implementation of the various packages.
- Effect is not imposed on the app developers using LiveStore but where it makes sense, LiveStore is also exposing a Effect-based API (e.g.
createStore
).
Updating dependencies
- Either update the versions manually in each
package.json
file or usebunx syncpack update
.
Notes on monorepo structure
- The
@livestore/utils
package re-exports many common modules/functions (e.g. fromeffect
) in order to- Reduce the number of direct dependencies for other packages
- Allows for convenient extension of modules (e.g. adding methods to
Effect.___
,Schema.___
, …)
Docs
The LiveStore docs are built with Astro Starlight.
Related external repos
- Fork of wa-sqlite and its Nix build setup.
- The source code of the devtools is currently not part of this monorepo but in a separate private repo.