Codync
무료 오픈소스 1:1 대안, Grok Bot과 Muse 대신
The JSX Discord interaction bot framework
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A composurejs bot is a function from Request to Response. There is no gateway connection to keep alive, so the same App runs on Cloudflare Workers, Node and Bun, and you test it by calling it.
import { App, Button, command, Container, Row, Text } from "composurejs"
const Counter = ({ count, owner }: { count: number; owner: string }) => (
<Container>
<Text>## Count: {count}</Text>
<Row>
<Button onClick={(c) => (c.user.id === owner ? <Counter count={count + 1} owner={owner} /> : c.ephemeral("Not yours"))}>
+1
</Button>
</Row>
</Container>
)
export default new App().command(
command({ name: "counter", description: "A counter", handler: (c) => <Counter count={0} owner={c.user.id} /> }),
)
The click handler lives on the button. There are no custom ids to invent and nothing to register: the Vite plugin hoists the handler, count and owner travel in the button's custom_id, and the markup the handler returns replaces the message.
pnpm create composurejs my-bot
Pick Cloudflare Workers, Node or Bun, give it your development application and a test server, then pnpm dev. It serves the bot, opens a tunnel, points the application at it and syncs your Commands. Type /counter in Discord.
The getting started guide walks through it.
onClick, onSelect and onSubmit take a function wherever the component is. A Handler Lock catches a deploy that would break buttons already sent.c.can(Permission.ManageMessages) for permission checks.c.defer(async () => ...) for slow work, and Auto Defer for handlers that turn out slow.vite dev tunnels to your machine, repoints your dev application, and re-syncs Commands to a test server on every save.composurejs/testing sends signed Interactions through the real pipeline and records what would have gone to Discord.| Runtime | How |
|---|---|
| Cloudflare Workers | export default app, built with @cloudflare/vite-plugin |
| Node 22.12+ | server() from @composurejs/vite builds a self-contained server |
| Bun | the same server build |
// vite.config.ts
import { cloudflare } from "@cloudflare/vite-plugin"
import composure from "@composurejs/vite"
import { defineConfig } from "vite"
export default defineConfig({ plugins: [composure(), cloudflare()] })
// Node or Bun: plugins: [composure(), server()]
import { answer, chatInput } from "composurejs/testing"
test("the button counts", async () => {
const first = await answer(app, chatInput("counter"))
const next = await answer(app, first.click("+1"))
expect(next.text).toContain("Count: 1")
})
Every request is signed with a real Ed25519 key and goes through the same pipeline as production. Nothing reaches Discord.
| Package | Version | |
|---|---|---|
composurejs | The framework: App, Commands, JSX, REST, testing | |
@composurejs/vite | Compiles inline handlers, builds for each runtime, runs the dev loop | |
@composurejs/cli | composure sync: puts your Commands on Discord | |
@composurejs/eslint-plugin | Flags components placed where Discord won't accept them, for ESLint and oxlint | |
create-composurejs | pnpm create composurejs |
discord-hono is also a Hono-like framework for Discord bots on Workers. composurejs differs in these ways:
composurejs is 0.x. It runs in production (this repo deploys its own bot), but the API may still change between minor versions. Changes are listed in each package's CHANGELOG and on the releases page.
It is a TypeScript port of the ideas in composure-rs.
| Path | What |
|---|---|
packages/composurejs | Core and subpaths: /jsx-runtime, /components, /testing, /rest, /sync, /placement |
packages/vite | composure() (inline handlers, the dev loop), server() (the Default Server) |
packages/cli | composure sync (also a library) |
packages/eslint-plugin | The placement rule |
packages/create-composurejs | One template generator for every runtime |
examples/bot | One App, built and run on workerd, Node and Bun by its tests |
bots/composure | composurejs's own bot, deployed to Workers |
docs | The guide (VitePress) and the ADRs |
CONTEXT.md | The glossary |
pnpm install
pnpm test # builds the packages, then every workspace test
pnpm typecheck # includes a Node-free check of core
pnpm size # bundle budgets
pnpm -C docs dev # the guide
Developing needs Node 22.18+ and pnpm. See CONTRIBUTING.md for checks and releases.