Writing Runners
Guide to creating custom runners with Hono
Overview
This guide covers everything you need to know about writing effective runners.
Basic Runner Structure
A runner is an async function that:
- Has the
"use runner"directive - Accepts
RunnerContextand optional input - Returns a
RunnerResult
The "use runner" Directive
The directive tells the discovery system that this function is a runner. It can be:
Function-Level (Recommended)
Module-Level
Best Practice: Use function-level directives for clarity and to avoid accidentally marking helper functions as runners.
Input and Output Validation
Runners support validation for both input and output using Zod or Standard Schema. Input schemas are validated at runtime, while output schemas provide TypeScript typing for the details field.
Input Validation
Use Zod schemas to validate and type your input:
The runner harness will automatically validate input against your schema before execution.
Output Validation
Define output schemas to type the details field in your results:
Using Playwright
For browser automation, use the withPlaywright() helper:
The withPlaywright() helper:
- Launches a browser instance
- Provides a
pageobject - Handles browser lifecycle
- Manages browser contexts
Runner Context
The RunnerContext provides:
Logging
Use ctx.log() for structured logging:
Region and Run ID
Access region and run ID from context:
Error Handling
Runners can throw errors, which are automatically caught and converted to error results:
Errors result in:
Best Practices
1. Use Descriptive Names
2. Validate Input
Always define input schemas:
3. Return Meaningful Details
4. Use Logging
Log important events:
5. Handle Edge Cases
Hono-Specific Notes
When writing runners for Hono (via Nitro):
- Runners work alongside your Hono routes
- Runner endpoints are automatically exposed at
/api/runner/* - Your Hono app continues to work normally
See Also
- Configuration - Configure runner discovery
- Deployment - Deploy Hono applications
- API Reference - Complete API documentation