Skip to content

🚀 Basicrum Local Development ​

This guide consists of instructions on how to run the full stack of Basicrum locally.

Prerequisites ​

This project uses mise to manage tool versions (Node.js, pnpm, Biome). Install it first:

bash
# macOS
brew install mise

Then activate it in your shell (add to ~/.zshrc or ~/.bashrc):

bash
eval "$(mise activate zsh)"

With mise installed, run the following in the project root to install the required tool versions:

bash
mise install

This installs the exact versions of Node.js, pnpm, and Biome defined in mise.toml.

TIP

Install the mise VS Code extension (recommended in .vscode/extensions.json) for automatic IDE integration.

The beacon_service is a Rust project. Install the Rust toolchain via rustup:

bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Preparation ​

Let's build our @basicrum/api_contract local package first.

bash
cd api_contract
pnpm install
pnpm build

Now our frontend and backend will be able to use the package.

You should also run the ClickHouse and Postgres docker containers from the project root:

bash
pnpm start-clickhouse
pnpm start-postgres

Installation ​

We use pnpm to manage our monorepo

To install all packages, run this in project root directory:

bash
pnpm install

To run the backend from the root directory:

bash
pnpm --filter @basicrum/backend dev

and similarly for frontend:

bash
pnpm --filter @basicrum/frontend dev

and the beacon service (this handles the incoming RUM beacons and writes to ClickHouse; the first run needs the GeoIP database, see beacon_service/README.md):

bash
cd beacon_service
./scripts/download-geoip.sh
cargo run

The commands above use pnpm's workspace feature to run the respective commands.

TIP

Just make sure you run the commands from different terminal window

Alternatively, we can also cd into the different folders separately and run pnpm run dev from there to achieve the same.

To install a new package in any of the workspaces, run this command from the root directory:

bash
pnpm --filter @basicrum/frontend add <package_name>

TIP

This will install the package in the frontend workspace. To install in the backend workspace, replace frontend with backend in the command above.

Postgres migrations ​

Postgres ​

We use postgres to store our non-clickhouse data. The database is manages by Drizzle ORM. Drizzle users the schema files in the src/postgres/schemas folder to manage the database schema. We can then use the following commands to generate the database migrations files. Please run it after you have made changes to the schema files.

bash

pnpm run generate-postgres-migration-files

This will generate the migration files in the src/postgres/migrations folder. You can then run the following command to apply the migrations.

bash

pnpm run run-postgres-migrations

This will run the migrations and create the database if it does not exist.

Updating the API contract ​

To update the API contract, you need to update the src/contract.ts file.

For more information, visit TS-REST website: https://ts-rest.com/docs/intro

After updating the contract, run the following command in the package's root directory:

bash
pnpm build

Then, update the package in the Frontend and Backend projects.

Beacon service (Rust) configuration ​

All configuration is read from environment variables. Defaults are provided for local development.

VariableDefaultDescription
BEACON_SERVICE_PORT3100Port to listen on
CLICKHOUSE_URLhttp://localhost:8123ClickHouse HTTP URL
CLICKHOUSE_USERdefaultClickHouse user
CLICKHOUSE_PASSWORDlocal_dev_passClickHouse password

Beacon service GeoIP database ​

asset/GeoLite2-City.mmdb is not checked into git. The version to use is pinned in geoip-version — a commit of wp-statistics/GeoLite2-City (which republishes MaxMind's GeoLite2 City database roughly twice a week) plus the sha256 of the download, verified by both the script and the Docker build. Local dev/tests and Docker image builds all download that same pinned version, so builds are reproducible.

bash
./scripts/download-geoip.sh          # download the pinned version (no-op if already on disk)
./scripts/download-geoip.sh --check  # show the pinned version and newer releases
./scripts/download-geoip.sh --bump   # pin the latest release and download it
./scripts/download-geoip.sh --force  # re-download the pinned version

To update the database, run --bump and commit the changed geoip-version file. The Docker build's download layer is cached until the pin changes.

Running the beacon service ​

Make sure ClickHouse is running (from the project root):

bash
pnpm start-clickhouse

Then start the service:

bash
cargo run