
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
**Reono** is an experimental library that enables you to define HTTP API endpoints using JSX syntax. The core package provides the JSX runtime, TypeScript definitions, and the efficient routing engine that powers the Reono ecosystem.
Reono is an experimental library that enables you to define HTTP API endpoints using JSX syntax. The core package provides the JSX runtime, TypeScript definitions, and the efficient routing engine that powers the Reono ecosystem.
The reono core package is responsible for:
npm install reono
# or
pnpm add reono
# or
yarn add reono
Define your API routes using familiar JSX syntax:
import { render } from 'reono';
const App = () => (
<router path="api">
<get path="users" handler={(c) => c.json([{ id: 1, name: "Alice" }])} />
<post
path="users"
validate={{ body: userSchema }}
handler={(c) => c.json({ id: 2, ...c.body })}
/>
<get
path="users/:id"
validate={{ params: z.object({ id: z.coerce.number() }) }}
handler={(c) => c.json({ id: c.params.id, name: "User" })}
/>
</router>
);
// Convert JSX to a request handler
const handler = render(<App />);
// Use with any server (Node.js, Bun, Deno, etc.)
const response = await handler(request);
<router>Groups routes under a common path prefix.
<router path="api/v1">
{/* All child routes will be prefixed with /api/v1 */}
</router>
Props:
path?: string | string[] - Path prefix for all child routeschildren?: Element | Element[] - Child route elementsDefine route handlers for specific HTTP methods.
<get path="users" handler={(c) => c.json(users)} />
<post path="users" handler={(c) => createUser(c.body)} />
<put path="users/:id" handler={(c) => updateUser(c.params.id, c.body)} />
<delete path="users/:id" handler={(c) => deleteUser(c.params.id)} />
<patch path="users/:id" handler={(c) => patchUser(c.params.id, c.body)} />
Props:
path?: string | string[] - Route path (supports parameters like :id)handler?: ApiHandler - Request handler functionvalidate?: ValidateSpec - Validation schemas for request data<use>Apply middleware to routes. Middleware runs before route handlers and can modify the request context.
<use handler={authMiddleware}>
<get path="protected" handler={(c) => c.json({ secret: "data" })} />
</use>
Props:
handler?: MiddlewareHandler - Middleware functionchildren?: Element | Element[] - Routes that will use this middlewareRoute handlers and middleware receive an ApiContext object:
type ApiContext = {
params: Record<string, any>; // Route parameters (e.g., :id)
body: any; // Parsed request body
json: (data: unknown, init?: number | ResponseInit) => Response;
req: Request; // Original Request object
res?: Response; // Response object (if available)
};
Reono supports schema-agnostic validation. Use any validation library that provides a parse method:
import { z } from 'zod';
const userSchema = z.object({
name: z.string(),
email: z.string().email(),
});
<post
path="users"
validate={{
body: userSchema,
params: z.object({ id: z.coerce.number() }),
query: z.object({ limit: z.coerce.number().optional() }),
headers: z.object({ 'x-api-key': z.string() })
}}
handler={(c) => {
// c.body, c.params, etc. are now type-safe and validated
}}
/>
ValidateSpec Properties:
body?: Schema<T> - Validate request bodyparams?: Schema<T> - Validate route parametersquery?: Schema<T> - Validate query parametersheaders?: Schema<T> - Validate request headersMiddleware functions receive the context and a next function:
const logger: MiddlewareHandler = async (c, next) => {
console.log(`${c.req.method} ${c.req.url}`);
const result = await next();
console.log('Request completed');
return result;
};
const auth: MiddlewareHandler = async (c, next) => {
const token = c.req.headers.get('authorization');
if (!token) {
return new Response('Unauthorized', { status: 401 });
}
return next();
};
Configure your tsconfig.json to use Reono's JSX runtime:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "reono"
}
}
Or use the classic JSX transform:
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "createElement"
}
}
<get path="users/:userId/posts/:postId" handler={(c) => {
const { userId, postId } = c.params;
// ...
}} />
<get path="files/*" handler={(c) => {
// Matches /files/any/nested/path
}} />
<router path="api">
<router path="v1">
<get path="users" handler={getUsersV1} />
</router>
<router path="v2">
<get path="users" handler={getUsersV2} />
</router>
</router>
Reono uses a highly optimized trie-based routing algorithm that provides:
The core package is framework-agnostic. Use it with:
@reono/node-server or any Node.js serverimport { render } from 'reono';
import { z } from 'zod';
const userSchema = z.object({
name: z.string(),
email: z.string().email(),
});
const logger = (c, next) => {
console.log(`${c.req.method} ${c.req.url}`);
return next();
};
const App = () => (
<use handler={logger}>
<router path="api/v1">
<router path="users">
<get path="" handler={(c) => c.json(getAllUsers())} />
<post
path=""
validate={{ body: userSchema }}
handler={(c) => c.json(createUser(c.body))}
/>
<get
path=":id"
validate={{ params: z.object({ id: z.coerce.number() }) }}
handler={(c) => c.json(getUser(c.params.id))}
/>
<put
path=":id"
validate={{
params: z.object({ id: z.coerce.number() }),
body: userSchema
}}
handler={(c) => c.json(updateUser(c.params.id, c.body))}
/>
<delete
path=":id"
validate={{ params: z.object({ id: z.coerce.number() }) }}
handler={(c) => deleteUser(c.params.id)}
/>
</router>
</router>
</use>
);
export default render(<App />);
ISC
This is an experimental library. Contributions, feedback, and discussions are welcome!
FAQs
**Reono** is an experimental library that enables you to define HTTP API endpoints using JSX syntax. The core package provides the JSX runtime, TypeScript definitions, and the efficient routing engine that powers the Reono ecosystem.
The npm package reono receives a total of 0 weekly downloads. As such, reono popularity was classified as not popular.
We found that reono demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.