Boxel
A new approach to building composable software, from Cardstack.
Install / Use
/learn @cardstack/BoxelREADME
Boxel Runtime
For a quickstart, see here
Setup
- you will want the Glint vscode extension
- you will want the vscode-glimmer vscode extension
- you will want the Playwright vscode extension
- this project uses mise for tool version management. Install mise and run
mise installfrom the repo root to get the correct Node.js and pnpm versions. - this project uses pnpm for package management. run
pnpm installto install the project dependencies first. - this project uses docker. Make sure to install docker on your system.
- Ensure that node_modules/.bin is in your path. e.g. include
export PATH="./node_modules/.bin:$PATH"in your .zshrc
Orientation
packages/host is the card runtime host application
packages/realm-server is a node app that serves the realm as an HTTP server, as well as, it can also host the runtime application for its own realm.
packages/boxel-ui/addon is the UI components Ember addon
packages/boxel-ui/test-app is the test suite and component explorer for boxel-ui, deployed at boxel-ui.stack.cards
packages/matrix is the docker container for running the matrix server: synapse, as well as tests that involve running a matrix client.
packages/ai-bot is a node app that runs a matrix client session and an OpenAI session. Matrix message queries sent to the AI bot are packaged with an OpenAI system prompt and operator mode context and sent to OpenAI. The ai bot enriches the OpenAI response and posts the response back into the matrix room.
packages/vscode-boxel-tools is a VS Code extension for browsing Boxel workspaces, published as Boxel Tools. It can be deployed via the bot, with staging environment producing a pre-release version.
packages/skills-realm is a realm that hosts AI skills. Skills are maintained in the boxel-skills repository and cloned locally for development. See the Skills Realm README for setup and development workflows.
Catalog Realms
There are two catalog realms running side by side:
| Realm | Source | URL path | Purpose |
| ---------------------- | --------------------------------------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------- |
| Catalog (monorepo) | packages/catalog-realm | /catalog/ | The existing catalog that ships from this monorepo. Currently used in production. |
| External Catalog | packages/catalog (clones boxel-catalog) | /external-catalog/ | A separate catalog maintained in its own repository. This is the future replacement for the monorepo catalog. |
Why two? Switching between monorepo and external catalog sources used to require rebuilding the host app and reindexing. By running both catalogs simultaneously, we can test the external repo catalog in staging and production alongside the existing one, without disrupting the current experience. The external catalog is gated behind a localStorage flag (boxel:externalCatalog) so it can be toggled on for testing without affecting other users.
Both catalogs are controlled by the same SKIP_CATALOG flag — setting SKIP_CATALOG=true skips setup and startup for both.
To learn more about Boxel and Cards, see our documentation
mise Tasks
Development services are managed as mise file-based tasks in mise-tasks/.
Task layout
mise-tasks/
lib/env-vars.sh # Shared env computation (sourced by .mise.toml)
infra/
ensure-traefik # Ensure Traefik is running (env mode only)
ensure-pg, stop-pg # Start/stop PostgreSQL
ensure-db # Ensure per-environment database exists
ensure-synapse # Ensure Synapse + user registration
start-synapse, stop-synapse # Start/stop Synapse manually
start-admin, stop-admin # Matrix admin console (port 8080)
wait-for-prerender # Wait for prerender server
services/
realm-server # Full development realm server
realm-server-base # Base realm only (for matrix tests)
worker, worker-base, # Worker managers
worker-test
prerender, prerender-mgr # Prerender server + manager
icons # Boxel icons HTTP server
host-build # Build and watch the host app
ai-bot # AI bot
bot-runner # Bot runner
dev # Full dev stack (realm server + workers + test realms)
dev-all # Host app + full dev stack (single command)
dev-minimal # Dev stack without optional realms
dev-without-matrix # Dev stack (expects Matrix already running)
build:ui # Build boxel-icons + boxel-ui (in dependency order)
test-services:host # Services for host test suite
test-services:matrix # Services for matrix test suite
test-services:realm-server # Services for realm-server test suite
ci:serve-test-assets # Serve icons + host dist (CI only)
stop-environment # Stop all services for an environment
All tasks automatically receive environment variables from mise-tasks/lib/env-vars.sh (service URLs, ports, database names, paths). In environment mode (BOXEL_ENVIRONMENT set), these point to Traefik hostnames with dynamic ports. In standard mode, they use fixed localhost ports.
To list all available tasks: mise tasks ls
Running the Host App
There exists a "dev" mode in which we can use ember-cli to host the card runtime host application which includes live reloads. Additionally, you can also use the realm server to host the app, which is how it will be served in production, or have staging or production as the backing infrastructure.
With staging or production
You can develop the host application locally backed by the staging or production infrastructure by running scripts/start-host [environment].
scripts/start-host production
…
Build successful (27238ms) – Serving on http://localhost:4200/
…
Visit http://localhost:4200 and log in with your staging or production credentials.
ember-cli Hosted App
Prerequisite:
Make sure that you have created a matrix user for the base and experiments realms. To make it easier, you can execute pnpm register-realm-users in packages/matrix/, this will create a matrix user for the base and experiments realms.
In order to run the ember-cli hosted app:
pnpm buildin the boxel-ui/addon workspace to build the boxel-ui addon.pnpm startin the host/ workspace to serve the ember app.mise run devfrom the repo root to serve the base and experiments realms -- this will also allow you to switch between the app and the tests without having to restart servers). This expects the Ember application to be running athttp://localhost:4200, if you’re running it elsewhere you can specify it withHOST_URL=http://localhost:5200 mise run dev.
Alternatively, you can run everything with a single command from the repo root:
mise run dev-all
This starts the host app first, waits for it to be ready, then starts the realm server and all supporting services.
The app is available at http://localhost:4200. You will be prompted to register an account. To make it easier, you can execute pnpm register-test-user in packages/matrix/. Now you can sign in with the test user using the credentials username: user, password: password.
When you are done running the app you can stop the synapse server:
mise run infra:stop-synapse
Realm server Hosted App
In order to run the realm server hosted app:
mise run services:host-buildto re-build the host app (this step can be omitted if you do not want host app re-builds)mise run devto serve the base and experiments realms
You can visit the URL of each realm server to view that realm's app. So for instance, the base realm's app is available at http://localhost:4201/base and the experiments realm's app is at http://localhost:4201/experiments.
Live reloads are not available in this mode, however, if you use start the server with the environment variable DISABLE_MODULE_CACHING=true you can just refresh the page to grab the latest code changes if you are running rebuilds (step #1 and #2 above).
Using mise run dev
Instead of running mise run services:realm-server-base, you can alternatively use mise run dev which also serves a few other realms on other ports--this is convenient if you wish to switch between the app and the tests without having to restart servers. For faster startup, mise run dev-minimal skips experiments, catalog, homepage, and submission realms. Use the environment variable WORKER_HIGH_PRIORITY_COUNT to add additional workers that service only user initiated requests and WORKER_ALL_PRIORITY_COUNT to add workers that service all jobs (system or user initiated). By default there is 1 all priority worker for each realm server. Here's what is spun up with mise run dev:
