<html lang="en">
<head></head>
<body>

<form id="mainForm" method="post" action="https://stackblitz.com/run" target="_self">
<input type="hidden" name="project[files][README.md]" value="# Custom Serverless

Example demonstrating custom serverless actor deployment with automatic engine configuration.

## Getting Started

```sh
git clone https://github.com/rivet-dev/rivet.git
cd rivet/examples/custom-serverless
npm install
npm run dev
```


## Features

- **Custom serverless deployment**: Configure and deploy actors to your own serverless infrastructure
- **Automatic engine configuration**: RivetKit automatically manages actor engine settings
- **Minimal setup**: Simple starter template for building custom deployments
- **Type-safe actions**: Full TypeScript support for actor definitions

## Implementation

This example shows how to deploy Rivet Actors to custom serverless platforms:

- **Actor Definition** ([`src/backend/registry.ts`](https://github.com/rivet-dev/rivet/tree/main/examples/custom-serverless/src/backend/registry.ts)): Demonstrates actor configuration for custom serverless deployment

## Resources

Read more about [setup](/docs/setup), [actions](/docs/actors/actions), and [state](/docs/actors/state).

## License

MIT
">
<input type="hidden" name="project[files][package.json]" value="{&quot;name&quot;:&quot;custom-serverless&quot;,&quot;version&quot;:&quot;2.0.21&quot;,&quot;private&quot;:true,&quot;type&quot;:&quot;module&quot;,&quot;scripts&quot;:{&quot;dev&quot;:&quot;npx srvx --import tsx src/server.ts&quot;,&quot;start&quot;:&quot;npx srvx --import tsx src/server.ts&quot;,&quot;check-types&quot;:&quot;tsc --noEmit&quot;,&quot;test&quot;:&quot;vitest run&quot;,&quot;build&quot;:&quot;tsup&quot;},&quot;devDependencies&quot;:{&quot;@types/node&quot;:&quot;^22.13.9&quot;,&quot;tsup&quot;:&quot;^8.0.0&quot;,&quot;tsx&quot;:&quot;^3.12.7&quot;,&quot;typescript&quot;:&quot;^5.7.3&quot;,&quot;vitest&quot;:&quot;^3.1.1&quot;},&quot;dependencies&quot;:{&quot;@hono/node-server&quot;:&quot;^1.19.7&quot;,&quot;@hono/node-ws&quot;:&quot;^1.3.0&quot;,&quot;hono&quot;:&quot;^4.0.0&quot;,&quot;rivetkit&quot;:&quot;https://pkg.pr.new/rivet-dev/rivet/rivetkit@b7a6ac3488d8d64f2cddf185312f05cf519f9413&quot;,&quot;srvx&quot;:&quot;^0.10.0&quot;},&quot;stableVersion&quot;:&quot;0.8.0&quot;,&quot;template&quot;:{&quot;technologies&quot;:[&quot;typescript&quot;],&quot;tags&quot;:[&quot;starter&quot;],&quot;noFrontend&quot;:true},&quot;license&quot;:&quot;MIT&quot;}">
<input type="hidden" name="project[files][tsconfig.json]" value="{
	&quot;compilerOptions&quot;: {
		/* Visit https://aka.ms/tsconfig.json to read more about this file */

		/* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
		&quot;target&quot;: &quot;esnext&quot;,
		/* Specify a set of bundled library declaration files that describe the target runtime environment. */
		&quot;lib&quot;: [&quot;esnext&quot;],
		/* Specify what JSX code is generated. */
		&quot;jsx&quot;: &quot;react-jsx&quot;,

		/* Specify what module code is generated. */
		&quot;module&quot;: &quot;esnext&quot;,
		/* Specify how TypeScript looks up a file from a given module specifier. */
		&quot;moduleResolution&quot;: &quot;bundler&quot;,
		/* Specify type package names to be included without being referenced in a source file. */
		&quot;types&quot;: [&quot;node&quot;],
		/* Enable importing .json files */
		&quot;resolveJsonModule&quot;: true,

		/* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
		&quot;allowJs&quot;: true,
		/* Enable error reporting in type-checked JavaScript files. */
		&quot;checkJs&quot;: false,

		/* Disable emitting files from a compilation. */
		&quot;noEmit&quot;: true,

		/* Ensure that each file can be safely transpiled without relying on other imports. */
		&quot;isolatedModules&quot;: true,
		/* Allow &#39;import x from y&#39; when a module doesn&#39;t have a default export. */
		&quot;allowSyntheticDefaultImports&quot;: true,
		/* Ensure that casing is correct in imports. */
		&quot;forceConsistentCasingInFileNames&quot;: true,

		/* Enable all strict type-checking options. */
		&quot;strict&quot;: true,

		/* Skip type checking all .d.ts files. */
		&quot;skipLibCheck&quot;: true,
		&quot;allowImportingTsExtensions&quot;: true,
		&quot;rewriteRelativeImportExtensions&quot;: true
	},
	&quot;include&quot;: [&quot;src/**/*.ts&quot;, &quot;tests/**/*.ts&quot;]
}
">
<input type="hidden" name="project[files][tsup.config.ts]" value="import { defineConfig } from &quot;tsup&quot;;

export default defineConfig({
	entry: {
		server: &quot;src/server.ts&quot;,
	},
	format: [&quot;esm&quot;],
	outDir: &quot;dist&quot;,
	bundle: true,
	splitting: false,
	shims: true,
});
">
<input type="hidden" name="project[files][turbo.json]" value="{
	&quot;$schema&quot;: &quot;https://turbo.build/schema.json&quot;,
	&quot;extends&quot;: [&quot;//&quot;],
	&quot;tasks&quot;: {
		&quot;build&quot;: {
			&quot;dependsOn&quot;: [&quot;rivetkit#build&quot;]
		}
	}
}
">
<input type="hidden" name="project[files][vercel.json]" value="{
	&quot;framework&quot;: &quot;hono&quot;
}
">
<input type="hidden" name="project[files][src/actors.ts]" value="import { actor, setup } from &quot;rivetkit&quot;;

const counter = actor({
	state: {
		count: 0,
	},
	actions: {
		increment: (c, x: number) =&gt; {
			c.state.count += x;
			c.broadcast(&quot;newCount&quot;, c.state.count);
			return c.state.count;
		},
		getCount: (c) =&gt; {
			return c.state.count;
		},
	},
});

export const registry = setup({
	use: { counter },
});

export type Registry = typeof registry;
">
<input type="hidden" name="project[files][src/server.ts]" value="import { Hono } from &quot;hono&quot;;
import { registry } from &quot;./actors.ts&quot;;

const app = new Hono();
app.all(&quot;/api/rivet/*&quot;, (c) =&gt; registry.handler(c.req.raw));
export default app;
">
<input type="hidden" name="project[files][tests/counter.test.ts]" value="import { setupTest } from &quot;rivetkit/test&quot;;
import { expect, test } from &quot;vitest&quot;;
import { registry } from &quot;../src/actors.ts&quot;;

test(&quot;it should count&quot;, async (test) =&gt; {
	const { client } = await setupTest(test, registry);
	const counter = client.counter.getOrCreate().connect();

	// Test initial count
	expect(await counter.getCount()).toBe(0);

	// Test event emission
	let eventCount = -1;
	counter.on(&quot;newCount&quot;, (count: number) =&gt; {
		eventCount = count;
	});

	// Test increment
	const incrementAmount = 5;
	const result = await counter.increment(incrementAmount);
	expect(result).toBe(incrementAmount);

	// Verify event was emitted with correct count
	expect(eventCount).toBe(incrementAmount);

	// Test multiple increments
	for (let i = 1; i &lt;= 3; i++) {
		const newCount = await counter.increment(incrementAmount);
		expect(newCount).toBe(incrementAmount * (i + 1));
		expect(eventCount).toBe(incrementAmount * (i + 1));
	}

	// Verify final count
	expect(await counter.getCount()).toBe(incrementAmount * 4);
});
">
<input type="hidden" name="project[description]" value="generated by https://pkg.pr.new">
<input type="hidden" name="project[template]" value="node">
<input type="hidden" name="project[title]" value="custom-serverless">
</form>
<script>document.getElementById("mainForm").submit();</script>

</body></html>