Monorepo
Prerequisites
Section titled “Prerequisites”Personal experience
Section titled “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
Section titled “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
Section titled “Manual setup”You’ll need to have a recent version the following tools installed:
- Node.js
- Bun
- pnpm
Initial setup
Section titled “Initial setup”git clone git@github.com:livestorejs/livestore.gitcd livestore# Loads env vars, installs deps and builds the project./bootstrap.sh
General notes
Section titled “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
Section titled “Notable used tools / technologies”Environment variables
Section titled “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
Section titled “VSCode tasks”- This project is primarily developed in VSCode and makes use of tasks to run commands.
- Common tasks are:
dev:ts:watch
to run the TypeScript compiler in watch mode for the entire monorepopnpm:install
to install all dependencies (e.g. when changing apackage.json
)
Tasks to run before committing
Section titled “Tasks to run before committing”Please run the following tasks before committing & pushing:
mono ts
to build the TypeScript codemono lint
to run the linting checksmono test
to run the tests
Examples
Section titled “Examples”- Once you’ve set up the monorepo locally, you’ll find all examples in the
/examples
directory. - All examples are self-contained and can be run independently.
- Examples use explicit version dependencies (e.g.,
0.3.2-dev.0
) for LiveStore packages. - Examples are not part of the monorepo TypeScript build system to maintain independence.
- Each example has its own TypeScript configuration that’s independent of the monorepo build system.
Making changes to examples
Section titled “Making changes to examples”- Make your desired changes directly in
/examples/<example-name>
. - Test your changes by running the example (e.g.,
pnpm dev
in the example directory). - Commit your changes.
OpenTelemetry setup
Section titled “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
Section titled “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
Section titled “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
Section titled “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
Section titled “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.17.2)
Effect
Section titled “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
Section titled “Updating dependencies”- Either update the versions manually in each
package.json
file or usebunx syncpack update
.
Notes on monorepo structure
Section titled “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.___
, …)
The LiveStore docs are built with Astro Starlight.
Related external repos
Section titled “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.