Skip to content

Quickstart

Start here when you want a new Junior app that follows the supported Hono, Nitro, and Vercel shape.

For production setup, complete Deploy to Vercel and Slack App Setup. Keep the manual Slack app creation step between the first live deployment and the deployment that adds Slack credentials.

Use the same baseline that the scaffolded CI workflow uses:

  • Node.js 24
  • pnpm
  • A Postgres database for Junior SQL records and the default memory plugin
  • A Redis URL for runtime state, locks, and durable task records

Slack credentials are needed before the bot can reply in Slack. You can scaffold and verify the local health route first, then finish Slack App Setup.

Run the initializer in an empty target directory:

Terminal window
pnpm dlx @sentry/junior init my-bot
cd my-bot
pnpm install

junior init creates the app entrypoint, Nitro config, Vercel config, TypeScript config, CI workflow, app context files, local plugin and skill directories, .env.example, and a plugins.ts with maintenance and memory enabled by default.

The generated app/ files have separate jobs:

FilePurpose
app/SOUL.mdAssistant voice and behavior.
app/WORLD.mdOperational context and domain knowledge.
app/DESCRIPTION.mdUser-facing app description.
app/skills/Local skills that are not owned by a plugin.
app/plugins/App-local plugin manifests and bundled plugin skills.

Do not recreate the old ABOUT.md; use WORLD.md and DESCRIPTION.md.

Copy .env.example to your local environment file, then generate one stable JUNIOR_SECRET:

Terminal window
node -e "console.log(require('node:crypto').randomBytes(32).toString('base64url'))"

Set these values before running real turns:

VariableRequiredPurpose
SLACK_SIGNING_SECRETYes, for Slack trafficVerifies Slack requests.
SLACK_BOT_TOKENYes, for Slack repliesPosts thread replies and calls Slack APIs.
DATABASE_URLYesPostgres connection string for Junior SQL records and memory.
JUNIOR_DATABASE_DRIVERNoSQL client driver: neon or postgres.
REDIS_URLYesRuntime state, locks, and durable background task records.
JUNIOR_SECRETYesSigns internal resume callbacks and sandbox actor context.
JUNIOR_BOT_NAMENoBot display/config name.
JUNIOR_SLASH_COMMANDNoSlack slash command name. Defaults to /jr.
AI_MODELNoStandard main-agent model override.
AI_FAST_MODELNoLightweight routing/classification model override.
AI_HANDOFF_MODELNoModel for the default handoff profile.
AI_MODEL_PROFILESNoJSON map of additional named handoff profiles.
AI_EMBEDDING_MODELNoEmbedding model override for plugin vector retrieval.
AI_VISION_MODELNoEnables image understanding when set.
AI_WEB_SEARCH_MODELNoSearch model override.
JUNIOR_STATE_KEY_PREFIXNoRedis key namespace for this local app/environment.

See Config & Environment for the full reference. If you keep the default memory plugin enabled, use a Postgres database with pgvector support before running migrations. Local Postgres URLs automatically use the postgres driver; set JUNIOR_DATABASE_DRIVER=postgres for other non-Neon Postgres providers.

Start the local dev server:

Terminal window
pnpm dev

The app listens on http://localhost:3000 by default.

Check the health route before wiring Slack:

Terminal window
curl http://localhost:3000/health

The response should include status: "ok".

After you complete Slack App Setup, point Slack at your tunnel URL and mention the bot in a thread. The reply should appear in the same thread.

New apps created with junior init already have a plugins.ts file with maintenance and memory enabled. To add more packaged plugins, install the packages and add them to the existing plugin set.

For an existing app created without a plugins.ts, create one as shown below.

Install only the plugins you plan to enable. If you are creating plugins.ts for an existing app, include the default maintenance and memory packages too:

Terminal window
pnpm add @sentry/junior-maintenance @sentry/junior-memory @sentry/junior-agent-browser @sentry/junior-amplitude @sentry/junior-cloudflare @sentry/junior-datadog @sentry/junior-github @sentry/junior-hex @sentry/junior-linear @sentry/junior-notion @sentry/junior-scheduler @sentry/junior-sentry @sentry/junior-vercel

Add them to the plugin set in plugins.ts:

plugins.ts
import { defineJuniorPlugins } from "@sentry/junior";
import { createMemoryPlugin } from "@sentry/junior-memory";
import { githubPlugin } from "@sentry/junior-github";
import { schedulerPlugin } from "@sentry/junior-scheduler";
export const plugins = defineJuniorPlugins([
createMemoryPlugin(),
"@sentry/junior-maintenance",
"@sentry/junior-agent-browser",
"@sentry/junior-amplitude",
"@sentry/junior-cloudflare",
"@sentry/junior-datadog",
githubPlugin({
botNameEnv: "GITHUB_APP_BOT_NAME",
botEmailEnv: "GITHUB_APP_BOT_EMAIL",
}),
"@sentry/junior-hex",
"@sentry/junior-linear",
"@sentry/junior-notion",
schedulerPlugin(),
"@sentry/junior-sentry",
"@sentry/junior-vercel",
]);

Point juniorNitro() at that module and pass the same plugin set to createApp() so local dev and built bundles use identical runtime plugins:

nitro.config.ts
import { defineConfig } from "nitro";
import { juniorNitro } from "@sentry/junior/nitro";
export default defineConfig({
preset: "vercel",
modules: [
juniorNitro({
plugins: "./plugins",
}),
],
routes: {
"/**": { handler: "./server.ts" },
},
});
server.ts
import { createApp } from "@sentry/junior";
import { plugins } from "./plugins.ts";
const app = await createApp({
plugins,
});
export default app;

Run the app check after changing plugins or skills:

Terminal window
pnpm check

The runtime-safe plugin set is also where runtime hooks are registered. schedulerPlugin() enables scheduled task tools and heartbeat behavior, and githubPlugin() enforces Git commit attribution. See Scheduler Plugin and GitHub Plugin for those setups.

When enabled plugins declare sandbox runtime dependencies, the scaffolded build runs snapshot warmup:

package.json
{
"scripts": {
"check": "junior check",
"dev": "nitro dev",
"build": "junior snapshot create && nitro build"
}
}

Run pnpm check before pnpm build so manifest and skill issues fail early.

Finish Slack App Setup so the bot can receive events, then follow Deploy to Vercel for production.