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".
Instrucciones de origen · Vista previa de solo lectura
name
miro-local-dev-loop
description
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.7.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),
},
});
Environment Variables
Variable
Required
Description
MIRO_ACCESS_TOKEN
Yes
OAuth 2.0 access token
MIRO_CLIENT_ID
For OAuth flow
App client ID
MIRO_CLIENT_SECRET
For OAuth flow
App client secret
MIRO_REDIRECT_URI
For OAuth flow
OAuth callback URL
MIRO_TEST_BOARD_ID
For integration tests
Board ID for live tests
Output
Following this guide produces the Miro integration outcome for its topic—configuration, validation evidence, operational recovery, or a documented migration result. Record command output and relevant identifiers so a failed step is traceable.
Examples
Start with the smallest applicable command or code example in the relevant section, using a dedicated test board and non-production credentials. Confirm the expected response or validation result before applying the pattern to production.