Starting a Cloudflare Worker from scratch
While tooling for web development is getting more and more complex, with CLIs for your CLIs becoming a thing, sometimes it's worth taking a step back, and realizing that doing things from scratch isn't so hard.
In this article, we're going to create and deploy a Cloudflare Worker without a CLI.
Table of contents
Steps to "Hello World"
- Make a new directory, and cd into it
mkdir my-worker/cd my-worker/
- Initialize the npm project
npm init -y
- Install some packages
npm install -D typescript wrangler @cloudflare/workers-types
- Create a
tsconfig.json
file
touch tsconfig.json
After running the above command, paste the following into tsconfig.json
:
//tsconfig.json{ "compilerOptions": { "noEmit": true, "module": "esnext", "target": "esnext", "lib": ["esnext"], "strict": true, "moduleResolution": "node", "types": ["@cloudflare/workers-types"] }}
- Make a
src/
directory, create an index.ts file inside
mkdir src/touch src/index.ts
After running the above command, paste the following into index.ts
:
// index.tsexport default { fetch: () => { return new Response('Hello World!'); },};
- Create a
wrangler.toml
file
touch wrangler.toml
After running the above command, paste the following into wrangler.toml
:
# wrangler.tomlname = "my-worker"main = "src/index.ts"compatibility_date = "2023-12-22"
- Login to wrangler
npx wrangler login
- Deploy your Worker
npx wrangler deploy
You can now visit the URL that wrangler outputs, and you should see "Hello World" in your browser.
- (optionally) Install vitest, add a test script
npm install vitest -Dtouch src/index.test.ts
After running the above commands, paste the following into src/index.test.ts
:
import { unstable_dev } from 'wrangler';import type { UnstableDevWorker } from 'wrangler';import { describe, expect, it, beforeAll, afterAll } from 'vitest';
describe('Worker', () => { let worker: UnstableDevWorker;
beforeAll(async () => { worker = await unstable_dev('src/index.ts', { experimental: { disableExperimentalWarning: true }, }); });
afterAll(async () => { await worker.stop(); });
it('should return Hello World', async () => { const resp = await worker.fetch(); if (resp) { const text = await resp.text(); expect(text).toMatchInlineSnapshot(`"Hello World!"`); } });});
Finally, in package.json
replace the test
script with:
"test": "vitest"
Summary
There you have it, a Cloudflare Worker from scratch.
While it's not strictly better than just running
npx wrangler@2 init my-worker2 -y
(which is the exact CLI command you'd run to get the project above)
At least this way you understand what's happening before reaching for tooling to automate it.