Configure Miro local development with hot reload, testing, and ngrok tunneling.
Use when setting up a development environment, configuring test workflows,
or establishing a fast iteration cycle with the Miro REST API v2.
Trigger with phrases like "miro dev setup", "miro local development",
"miro dev environment", "develop with miro", "miro testing".
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Configure Miro local development with hot reload, testing, and ngrok tunneling.
Use when setting up a development environment, configuring test workflows,
or establishing a fast iteration cycle with the Miro REST API v2.
Trigger with phrases like "miro dev setup", "miro local development",
"miro dev environment", "develop with miro", "miro testing".
allowed-tools
Read, Write, Edit, Bash(npm:*), Bash(npx:*), Grep
version
1.6.0
license
MIT
author
Jeremy Longshore <jeremy@intentsolutions.io>
tags
["saas","miro","development","testing"]
compatibility
Designed for Claude Code
Miro Local Dev Loop
Overview
Set up a fast local development workflow for building Miro integrations, including hot reload, test mocking against the REST API v2, and ngrok tunneling for webhooks.
Prerequisites
Completed miro-install-auth setup
Node.js 18+ with npm or pnpm
Access token with boards:read and boards:write scopes
{"scripts":{"dev":"tsx watch src/index.ts","test":"vitest","test:watch":"vitest --watch","test:integration":"MIRO_TEST_MODE=live vitest run tests/integration/","tunnel":"ngrok http 3000","typecheck":"tsc --noEmit"},
"dependencies"
:
{
"@mirohq/miro-api"
:
"^2.0.0"
,
"express"
:
"^4.18.0"
,
"dotenv"
:
"^16.0.0"
}
,
"devDependencies"
:
{
"tsx"
:
"^4.0.0"
,
"vitest"
:
"^1.0.0"
,
"typescript"
:
"^5.0.0"
}
}
Step 3: Miro Client Singleton
// src/miro/client.tsimport { MiroApi } from'@mirohq/miro-api';
letinstance: MiroApi | null = null;
exportfunctiongetMiroApi(): MiroApi {
if (!instance) {
const token = process.env.MIRO_ACCESS_TOKEN;
if (!token) thrownewError('MIRO_ACCESS_TOKEN not set');
instance = newMiroApi(token);
}
return instance;
}
// For testing โ allow injecting a mockexportfunctionresetMiroApi(): void {
instance = null;
}
Step 4: Test Fixtures from Real API Responses
// tests/fixtures/board.json{"id":"uXjVN1234567890","type":"board","name":"Test Board","description":"Fixture for unit tests","createdAt":"2025-01-15T10:00:00Z","modifiedAt":"2025-01-15T10:30:00Z","owner":{"id":"123456","type":"user","name":"Dev User"},"policy":{"sharingPolicy":{"access":"private"},"permissionsPolicy":{"collaborationToolsStartAccess":"all_editors"}}}
# Start your dev server
npm run dev
# In another terminal, start ngrok
ngrok http 3000
# Copy the HTTPS URL (e.g., https://abc123.ngrok.app)# Register it as a webhook callback in your Miro app settings# or via the API (see miro-webhooks-events skill)
Step 7: Debug Logging
// Enable verbose HTTP logging during developmentimport { MiroApi } from'@mirohq/miro-api';
// Log all API requests and responsesconst api = newMiroApi(process.env.MIRO_ACCESS_TOKEN!, {
logger: {
info: (...args) =>console.log('[MIRO]', ...args),
warn: (...args) =>console.warn('[MIRO]', ...args),
error: (...args) =>console.error('[MIRO]', ...args),
},
});