Quickstart
Start here when you want a new Junior app that follows the supported Hono, Nitro, and Vercel shape.
Prerequisites
Section titled “Prerequisites”Use the same baseline that the scaffolded CI workflow uses:
- Node.js 24
- pnpm
- A Redis URL for queue and state storage
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.
Create a new app
Section titled “Create a new app”Run the initializer in an empty target directory:
pnpm dlx @sentry/junior init my-botcd my-botpnpm installjunior init creates the app entrypoint, Nitro/Vite config, Vercel config, Vercel queue consumer source, CI workflow, app context files, local plugin and skill directories, and .env.example.
The generated app/ files have separate jobs:
| File | Purpose |
|---|---|
app/SOUL.md | Assistant voice and behavior. |
app/WORLD.md | Operational context and domain knowledge. |
app/DESCRIPTION.md | User-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.
Configure environment
Section titled “Configure environment”Copy .env.example to your local environment file, then generate one stable JUNIOR_SECRET:
node -e "console.log(require('node:crypto').randomBytes(32).toString('base64url'))"Set these values before running real turns:
| Variable | Required | Purpose |
|---|---|---|
SLACK_SIGNING_SECRET | Yes, for Slack traffic | Verifies Slack requests. |
SLACK_BOT_TOKEN | Yes, for Slack replies | Posts thread replies and calls Slack APIs. |
REDIS_URL | Yes | Queue and runtime state storage. |
JUNIOR_SECRET | Yes | Signs internal resume callbacks and sandbox requester context. |
JUNIOR_BOT_NAME | No | Bot display/config name. |
JUNIOR_SLASH_COMMAND | No | Slack slash command name. Defaults to /jr. |
AI_MODEL | No | Primary assistant model override. |
AI_FAST_MODEL | No | Lightweight routing/classification model override. |
AI_VISION_MODEL | No | Enables image understanding when set. |
AI_WEB_SEARCH_MODEL | No | Search model override. |
JUNIOR_STATE_KEY_PREFIX | No | Redis key namespace for this local app/environment. |
See Config & Environment for the full reference.
Run locally
Section titled “Run locally”Start the local dev server:
pnpm devThe app listens on http://localhost:3000 by default.
Verify locally
Section titled “Verify locally”Check the health route before wiring Slack:
curl http://localhost:3000/healthThe 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.
Add packaged plugins
Section titled “Add packaged plugins”Packaged plugins must be installed and explicitly listed in the plugin set
referenced by juniorNitro so Nitro bundles their manifests, skills, hooks,
and runtime dependencies.
Install only the plugins you plan to enable:
pnpm add @sentry/junior-agent-browser @sentry/junior-datadog @sentry/junior-github @sentry/junior-hex @sentry/junior-linear @sentry/junior-notion @sentry/junior-scheduler @sentry/junior-sentry @sentry/junior-vercelThen create one runtime-safe plugin set:
import { defineJuniorPlugins } from "@sentry/junior";import { githubPlugin } from "@sentry/junior-github";import { schedulerPlugin } from "@sentry/junior-scheduler";
export const plugins = defineJuniorPlugins([ "@sentry/junior-agent-browser", "@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",]);Point juniorNitro() at that module. createApp() reads the same plugin set
from Nitro’s virtual module, so the server entry does not repeat it:
import { defineConfig } from "nitro";import { juniorNitro } from "@sentry/junior/nitro";
export default defineConfig({ preset: "vercel", modules: [ juniorNitro({ plugins: "./plugins", }), ], routes: { "/**": { handler: "./server.ts" }, },});import { createApp } from "@sentry/junior";
const app = await createApp();
export default app;Run the app check after changing plugins or skills:
pnpm checkThe runtime-safe plugin set is also where trusted 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.
Verify plugin content
Section titled “Verify plugin content”When enabled plugins declare sandbox runtime dependencies, the scaffolded build runs snapshot warmup:
{ "scripts": { "check": "junior check", "dev": "vite dev", "build": "junior snapshot create && vite build" }}Run pnpm check before pnpm build so manifest and skill issues fail early.
Next step
Section titled “Next step”Finish Slack App Setup so the bot can receive events, then follow Deploy to Vercel for production.