Complete developer guide for contributing to this project or building and deploying your own version.
Built on Cloudflare Workers with Wrangler.
Note: this project uses npm to manage development dependencies, including Wrangler and TypeScript.
The project provides a pre-configured Dev Container environment for GitHub Codespaces, making it quick and easy to start coding.
✅ Using Codespaces is the recommended way to work on the project, since it automatically sets up the required elements and provides a ready-to-code environment.
First, create a fork of the repository by following the GitHub guide on forking a repo.
You will obtain a repository containing your own copy of the project on your GitHub account, which allows you to use the project, make modifications, and share them with the maintainer via a pull request if you wish.
Before you start a new Codespaces environment and begin coding in it, you need to register the required secrets (in this project, only one secret is required) in the repository's GitHub Codespaces secrets.
See the environment variables section for the required configuration and the GitHub Codespaces documentation about secrets for more details.
Open the repository on GitHub and create a new Codespace from the Code → Codespaces menu.
GitHub will automatically detect the project's .devcontainer.json configuration and build the development environment.
The .devcontainer.json file:
{
"name": "MeteoritesAPI Codespace setup script",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "24"
}
},
"postCreateCommand": "npm install && echo \"IP_HASH_SALT=\\\"$IP_HASH_SALT\\\"\" > .dev.vars && npm run types",
"remoteUser": "vscode"
}defines the Codespace development environment:
| Component | Configuration |
|---|---|
| Base image | Ubuntu-based development container |
| Node.js | Version 24 |
| Cloudflare Wrangler | Installed locally through npm dependencies |
| Environment variables | Populated from the Codespaces environment and written to .dev.vars |
| TypeScript definitions | Generated with wrangler types through npm run types |
| Remote user | vscode |
The postCreateCommand automatically performs the required setup when the Codespace is created.
Wrangler is installed locally through npm dependencies to ensure a reproducible development environment across local machines, Codespaces, and CI workflows. This is also the approach now strongly recommended by Cloudflare for developers — see the Wrangler install & update guide.
⚠️ Note:.dev.varsis a local development file and must never be committed to the repository. It is already included in.gitignore.
Once the Codespace has finished initializing, authenticate Wrangler with your Cloudflare account:
npm run loginReview the wrangler.jsonc file, which contains the complete project configuration:
| Field | Purpose |
|---|---|
name |
Defines the Worker project name. This determines your public URL (e.g., https://project-name.your-subdomain.workers.dev). |
main |
Specifies the entry point of your Worker script. This file exports your main fetch handler. |
compatibility_date |
Locks your Worker to a specific Cloudflare Workers runtime version, ensuring compatibility even as Cloudflare updates the platform. |
preview_urls |
Enables (true) or disables (false) preview URLs for testing. |
| Field | Purpose |
|---|---|
observability.enabled |
When true, enables automatic metrics and logs collection, allowing performance and error monitoring in the Cloudflare dashboard. |
observability.head_sampling_rate |
Defines the percentage of requests sampled for tracing (0 to 1) — 1 = 100% sampling (useful for debugging), 0.1 = 10% sampling (better for production). |
observability.logs.invocation_logs |
Controls automatic invocation log collection — true logs request metadata, headers, and execution details; false disables automatic logs, keeping only custom console.log entries. |
observability.traces.enabled |
Controls distributed tracing — true enables tracing spans and trace IDs, false disables tracing entirely. |
🔒 Disabling
invocation_logsis recommended for GDPR compliance, to prevent storage of sensitive request data.Leave
traces.enableddisabled if not using OpenTelemetry or a tracing system.
The Worker uses standard environment variables in a .dev.vars file for local development, and Cloudflare Workers Secrets for deployed Workers in production.
Variable used in this project:
| Variable | Description |
|---|---|
IP_HASH_SALT |
The salt used to hash IP addresses. |
Create/configure the value above as GitHub Codespaces secrets.
When the Codespace is created,
.devcontainer.jsonautomatically writes it to.dev.vars, as explained above.
For the deployed Worker, configure the same value (rigorously, IP_HASH_SALT can be different in local and in production) as a Cloudflare Workers Secret:
wrangler secret put IP_HASH_SALT| Variable | Requirements |
|---|---|
IP_HASH_SALT |
A strong value with at least 30 characters, including uppercase and lowercase letters and numbers. |
⚠️ IP_HASH_SALTis a sensitive secret and must be handled with extreme caution. You may use scripts or tools to generate it, but make sure you never leak, log, or expose it.
Take a look at the config.ts file at the root of the project, which looks like:
export const config: StaticConfig = {
RATE_LIMIT_INTERVAL_S: 1, // Min: 1
MAX_RANDOM_METEORITES: 1000, // Min: 100
MAX_RETURNED_SEARCH_RESULTS: 500, // Min: 100
MIN_RADIUS: 1, // Min: 1
MAX_RADIUS: 2500, // Min: 1000
DEFAULT_RANDOM_NUMBER_OF_METEORITES: 100 // Min: 100
};Configuration parameters:
| Parameter | Description | Constraint |
|---|---|---|
RATE_LIMIT_INTERVAL_S |
Rate limit interval in seconds | Minimum: 1 second |
MAX_RANDOM_METEORITES |
Maximum meteorites returned by /random |
Minimum: 100 meteorites |
MAX_RETURNED_SEARCH_RESULTS |
Maximum meteorites returned by /search |
Minimum: 100 meteorites |
MIN_RADIUS |
Minimum allowed search radius (km) | Minimum: 1 km |
MAX_RADIUS |
Maximum allowed search radius (km) | Minimum: 1000 km |
DEFAULT_RANDOM_NUMBER_OF_METEORITES |
Default count for /random if not specified |
Minimum: 100 meteorites |
Note:
MAX_RANDOM_METEORITESmust always be greater thanDEFAULT_RANDOM_NUMBER_OF_METEORITES. Violating these constraints will trigger a configuration error.
Once your Codespace is ready and your Cloudflare account is authenticated, you're ready to start coding. This section provides an overview of how the TypeScript types are initialized, as well as how to run and deploy the project.
The Dev Container automatically runs npm run types when the Codespace is created. This executes Wrangler's type generation command and creates the TypeScript definitions required by the Worker in worker-configuration.d.ts.
If you change your Wrangler configuration, regenerate the definitions manually with:
npm run typesEnsure
wrangler.jsoncis properly configured before regenerating the types.
The generated definitions are automatically picked up by TypeScript through the types option in tsconfig.json:
{
"compilerOptions": {
"noEmit": true,
"allowImportingTsExtensions": true,
"target": "ES2020",
"lib": ["ES2020", "DOM"],
"module": "ESNext",
"moduleResolution": "Bundler",
"verbatimModuleSyntax": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"types": ["./worker-configuration.d.ts"],
"resolveJsonModule": true
},
"include": ["utilities", "worker-configuration.d.ts", "main.ts", "config.ts", "types"],
"exclude": ["node_modules", "dist"]
}TypeScript configuration explanation
| Setting | Purpose |
|---|---|
noEmit: true |
Prevents TypeScript from emitting JavaScript locally; Wrangler handles bundling. |
allowImportingTsExtensions: true |
Allows direct .ts file imports for relative paths. |
target: "ES2020" |
Uses modern JavaScript syntax supported by the Workers runtime. |
lib: ["ES2020", "DOM"] |
Includes modern JavaScript features and Web APIs such as fetch, Request, and Response. |
module: "ESNext" |
Uses the ES Modules standard for Workers. |
moduleResolution: "Bundler" |
Configures module resolution for bundler-based ESM environments. |
verbatimModuleSyntax: true |
Preserves module syntax as written and requires explicit import type for type-only imports. |
strict: true |
Enables strict type-checking for safer code. |
esModuleInterop: true |
Facilitates interoperability with CommonJS modules. |
skipLibCheck: true |
Skips type checking for .d.ts files to speed up type checking. |
forceConsistentCasingInFileNames: true |
Prevents file casing errors across operating systems. |
noUnusedLocals: true |
Reports unused local variables, functions, and imports. |
noUnusedParameters: true |
Reports unused function parameters. |
noImplicitReturns: true |
Ensures that all code paths in a function return a value when a return value is expected. |
noFallthroughCasesInSwitch: true |
Reports switch cases that unintentionally fall through to the next case. |
allowUnreachableCode: false |
Reports code that can never be reached. |
allowUnusedLabels: false |
Reports unused JavaScript labels. |
types: ["./worker-configuration.d.ts"] |
Loads the TypeScript definitions generated by Wrangler. |
resolveJsonModule: true |
Allows importing JSON files as modules. |
include |
Specifies the source files and types to type-check. |
exclude |
Specifies build artifacts and dependencies to ignore. |
Start local development:
npm run devFormat code:
Run Prettier to automatically format the codebase:
npm run formatDeploy to Cloudflare Workers:
⚠️ Make sure your Cloudflare Workers Secrets (for deployed Workers) have been configured before deploying — see environment variables.
npm run deployIf the Worker is configured to use a workers.dev subdomain, Wrangler will display the deployed URL.
For issues or questions, open an issue on GitHub.
{ "name": "project-name", "main": "main.ts", "compatibility_date": "2026-08-12", "preview_urls": false, "observability": { "enabled": true, "head_sampling_rate": 1, "logs": { "invocation_logs": false }, "traces": { "enabled": false } } }