Gyoka is a edge server for Bluesky custom feed generators, running on Cloudflare Workers with D1 database. It serves feed skeletons to Bluesky/AppView and provides an API to manage the post list for each feed.
To populate feeds, you need a separate post-collection component that discovers relevant posts via Firehose, Jetstream, or other means, and registers or removes them through the editor API.
gyoka-generator: public feed skeleton endpoint for Bluesky/AppViewgyoka-editor: private API for managing feeds and posts
- Edge-native: Runs on Cloudflare Workers worldwide — low latency response to Bluesky/AppView requests.
- Decoupled by design: Post collection is fully separated from feed serving. AppView sees only the generator endpoint; collectors and their logic are hidden behind the private editor API.
- Multiple feeds, single deployment: Manage any number of feeds from one worker instance.
- AT Protocol ready: DID document of feed generator, feed skeleton pagination, and Service JWT verification are supported.
- Rich management API: Batch add/remove, per-author removal, feed trimming, and active/inactive toggling via the editor REST API.
Gyoka supports:
- Feed generator endpoints
/xrpc/app.bsky.feed.getFeedSkeleton/xrpc/app.bsky.feed.describeFeedGenerator/.well-known/did.json/doc(for terms of service and privacy policy documents)
- Language tag filtering on
/xrpc/app.bsky.feed.getFeedSkeletonvia request headers - JWT verification on
/xrpc/app.bsky.feed.getFeedSkeletonwith cached DID document resolution
Gyoka does not support in this version:
- Feed interactions
(
acceptsInteractionsinapp.bsky.feed.generatorrecord must befalse) - Feed management via XRPC endpoints (the editor worker exposes an OpenAPI endpoints instead)
packages/generator: generator guidepackages/editor: editor guidepackages/shared: shared library and migrationsdocs/create-feed.md: how to create feed recordsdocs/edit-feed.md: how to edit feed data
- Node.js v22 or later
- pnpm v10 or later
- Wrangler v4
- Cloudflare account
-
Clone this repository and install dependencies.
pnpm install
-
Create D1 database and keep the returned
database_id.pnpm d1-create # or with location pnpm d1-create --location wnamAdd the
--locationoption to create the D1 database in a specific location. See wrangler D1 create document. -
Configure production settings.
- Set production
database_idin:packages/editor/wrangler.jsoncpackages/generator/wrangler.jsonc
- Configure worker vars (details in each package README):
- generator vars: see packages/generator/README.md
- editor vars: see packages/editor/README.md
- Set production
-
Initialize production schema.
pnpm d1-init:production
-
Deploy both workers.
pnpm editor run deploy pnpm generator run deploy
-
Set editor API key secret for production.
pnpm editor gyoka-api-key:put
[!NOTE]
X-API-Keyprovides minimal authentication only. For production use, combining with an additional authentication layer such as Cloudflare One is strongly recommended. -
Create and manage feeds.
- How to create feeds: docs/create-feed.md
- How to edit feeds: docs/edit-feed.md
-
Initialize local D1 and optional sample data.
pnpm d1-init:local pnpm d1-add-sample:local
-
Start workers.
pnpm editor dev pnpm generator dev
-
Open endpoints.
- generator DID document:
http://localhost:8788/.well-known/did.json - editor OpenAPI docs (dev):
http://localhost:8787/docs- Default API key is
devset in.dev.vars
- Default API key is
- generator DID document:
- Workspace all tests:
pnpm test:all - Package-specific examples:
pnpm generator test runpnpm editor test runpnpm shared test run
MIT License