docs/versioned_docs/version-v0.32.0/08-development/01-setup.md
For the fastest way to get started with development, use the one-command setup script:
./start-dev.sh
This script will automatically:
pnpm install if neededPrerequisites:
The script will output the running services:
Press Ctrl+C to stop all services and clean up Docker containers.
Alternatively, you can use Docker Compose to run the full stack in containers — see Docker Compose Details below.
Karakeep uses node version 24. To install it, you can use nvm 1
$ nvm install 24
Verify node version using this command:
$ node --version
v24.0.0
Karakeep also makes use of corepack2. If you have node installed, then corepack should already be
installed on your machine, and you don't need to do anything. To verify the corepack is installed run:
$ command -v corepack
/home/<user>/.nvm/versions/node/v22.14.0/bin/corepack
To enable corepack run the following command:
$ corepack enable
Then, from the root of the repository, install the packages and dependencies using:
$ pnpm install
Output of a successful pnpm install run should look something like:
Scope: all 20 workspace projects
Lockfile is up to date, resolution step is skipped
Packages: +3129
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 0, reused 2699, downloaded 0, added 3129, done
devDependencies:
+ @karakeep/prettier-config 0.1.0 <- tooling/prettier
. prepare$ husky
└─ Done in 45ms
Done in 5.5s
You can now continue with the rest of this documentation.
/apps/web, /apps/workers) and also /packages/db.cp .env.sample .env.DATA_DIR: Where the database and assets will be stored. This is the only required env variable. You can use an absolute path so that all apps point to the same dir.NEXTAUTH_SECRET: Random string used to sign the JWT tokens. Generate one with openssl rand -base64 36. Logging in will not work if this is missing!MEILI_ADDR: If not set, search will be disabled. You can set it to http://127.0.0.1:7700 if you run meilisearch using the command below.OPENAI_API_KEY: If you want to enable auto tag inference in the dev env.pnpm run db:migrate in the root of the repo to set up the database.Meilisearch is the provider for the full text search (and at some point embeddings search too). You can get it running with docker run -p 7700:7700 getmeili/meilisearch:v1.41.0.
Mount persistent volume if you want to keep index data across restarts. You can trigger a re-index for the entire items collection in the admin panel in the web app.
The worker app will automatically start headless chrome on startup for crawling pages. You don't need to do anything there.
pnpm web in the root of the repo.http://localhost:3000.NOTE: The web app kinda works without any dependencies. However, search won't work unless meilisearch is running. Also, new items added won't get crawled/indexed unless workers are running.
pnpm workers in the root of the repo.To build and run the mobile app locally, you'll need:
For iOS development:
For Android development:
For detailed setup instructions, refer to the Expo documentation.
If you are returning to mobile development after a significant update to the source (e.g. Expo version bump or major dependency changes), the build may fail with stale artifacts in workspace node_modules. Run a clean wipe before reinstalling:
pnpm run clean:workspaces
pnpm install
pnpm --filter @karakeep/mobile clean:prebuild
Then continue with the prebuild and run steps below.
# ios
pnpm ios
# android
pnpm android
More details below if you want to understand what's going on.
The app has three variants: development, preview, and release.
| Variant | Description | Expo Dev Tools | Command (iOS) | Command (Android) |
|---|---|---|---|---|
| Development (default) | Requires the expo devserver to be running. Uses a separate bundle ID so it can be installed alongside the production app. | Yes | pnpm ios | pnpm android |
| Preview | Standalone app that doesn't require the expo devserver. Uses its own bundle ID. | No | pnpm --filter @karakeep/mobile ios:preview | pnpm --filter @karakeep/mobile android:preview |
| Release | Standalone app using the production bundle ID. Closest to a production build. | No | pnpm --filter @karakeep/mobile ios:release | pnpm --filter @karakeep/mobile android:release |
In 90% of the cases, you'll want to use the development variant.
Note: Changing the code will hot reload the app. However, installing new packages requires restarting the expo server.
cd apps/browser-extensionpnpm devdist packageLoad unpacked and point it to the dist directory.In dev mode, opening and closing the plugin menu should reload the code.
If you prefer to run the full stack inside Docker, follow these steps:
cp .env.sample .env
DATA_DIR=/data, MEILI_ADDR=http://meilisearch:7700, NEXTAUTH_URL=http://localhost:3000, and NEXTAUTH_SECRET=super-secure-nextauth-secret.NEXTAUTH_SECRET (use openssl rand -base64 36) and any optional keys like OPENAI_API_KEY inside .env so they override the defaults./data inside the containers, so you only need to change DATA_DIR if you prefer a host path.docker compose -f docker/docker-compose.dev.yml up
prep service creates DATA_DIR (if missing), runs pnpm install --frozen-lockfile, and then pnpm run db:migrate the first time (and whenever you restart the stack) so the rest of the services always have dependencies ready.web and workers services run pnpm web and pnpm workers respectively using the same code that lives on your host machine, so hot reload works out of the box.docker compose logs -f web workers
docker compose down. Re-run with --build if you change Node dependencies or the Dockerfile.This setup exposes:
Meilisearch runs as an internal service only (no host port exposed).
docker compose -f docker/docker-compose.dev.yml up starts five services:
prep: installs dependencies and runs database migrations before anything else boots.web: runs pnpm web with hot reload enabled (polling watchers are turned on for reliable Mac/Windows file sync).workers: runs pnpm workers so crawlers, importers, and background jobs behave the same way as in local dev.meilisearch: exposes http://localhost:7700 with analytics disabled and persistent data stored in the meilisearch Docker volume.chrome: provides the remote-debuggable Chrome instance required by the workers on http://localhost:9222.All application containers mount your checkout into /app and share two volumes: node_modules (so dependencies live inside Linux containers) and pnpm-store (to keep the pnpm cache). If you ever need a clean slate you can remove them with:
docker compose -f docker/docker-compose.dev.yml down -v
Every environment value is defined with ${VAR:-default} syntax, so the stack boots even if .env is missing; create the file only when you want to override something like NEXTAUTH_SECRET or MEILI_MASTER_KEY.
You can override the default /data mount by editing DATA_DIR in .env and binding a host directory via a regular Docker volume mapping. Any other environment variable defined in .env is automatically propagated to the Node services.
nvm is a node version manager. You can install it following these instructions. ↩
corepack is an experimental tool to help with managing versions of your package managers. ↩