{"id":51337734,"url":"https://github.com/temporalio/nex-gen","last_synced_at":"2026-07-02T04:30:46.742Z","repository":{"id":361911559,"uuid":"1222988370","full_name":"temporalio/nex-gen","owner":"temporalio","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-30T15:19:31.000Z","size":1713,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T17:14:56.144Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/temporalio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-27T22:51:28.000Z","updated_at":"2026-06-30T15:20:23.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/temporalio/nex-gen","commit_stats":null,"previous_names":["temporalio/nex-gen"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/temporalio/nex-gen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporalio%2Fnex-gen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporalio%2Fnex-gen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporalio%2Fnex-gen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporalio%2Fnex-gen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/temporalio","download_url":"https://codeload.github.com/temporalio/nex-gen/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporalio%2Fnex-gen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35033488,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-02T04:30:44.494Z","updated_at":"2026-07-02T04:30:46.715Z","avatar_url":"https://github.com/temporalio.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nex-gen\n\n\u003e [!WARNING]\n\u003e This repository is experimental. Generated APIs, input formats, and CLI behavior\n\u003e may change without compatibility guarantees.\n\nRust CLI for generating language-specific Nexus operation bindings from WIT.\n\nThe WIT definition is the source of truth for the public API. Protobuf descriptor sets are optional and are only needed when the WIT opts into proto-backed models or when using `add-rpc` to scaffold WIT from an existing proto RPC.\n\n## Contents\n\n- [Examples](#examples)\n- [WIT-Direct Generation](#wit-direct-generation)\n- [WIT Directives](#wit-directives)\n- [Runtimes](#runtimes)\n- [Proto Backing](#proto-backing)\n- [Validation](#validation)\n\nCurrent status:\n\n- .NET generation is implemented\n- Python generation is implemented\n- TypeScript generation is implemented\n- WIT records, enums, flags, variants, results, resources, resource methods, and no-result operations are supported without proto backing\n- proto-backed request models can serialize into proto inputs when WIT types are annotated with `@nexus.proto`\n- proto-backed response and nested models remain bidirectional where generated\n- support files, native type substitutions, sourced fields, function metadata, flattened API fields, and output transforms are driven from WIT `@nexus` directives\n\n## Examples\n\nEach example starts with authored WIT under `examples/inputs/`. Checked-in\ngenerated output lives under `examples/python/\u003cexample_name\u003e/` and\n`examples/typescript/\u003cexample-name\u003e/`; .NET output lives under\n`examples/dotnet/\u003cexample-name\u003e/`. Language-specific tests live under each\nlanguage's `tests/` directory where present. See [`examples/README.md`](examples/README.md)\nfor links to each example's WIT, generated code, and tests.\n\n- [`user-service`](examples/inputs/user-service.wit): a small WIT-direct API showing the basic shape of an operation returning a resource and a resource method that calls another operation.\n- [`type-showcase`](examples/inputs/type-showcase.wit): a WIT-direct API focused on type coverage, including records, enums, flags, variants, results, maps, tuples, resources, resource methods, and no-result operations.\n- [`start-workflow`](examples/inputs/start-workflow.wit): a proto-backed Temporal workflow-start API that returns a generated resource handle with follow-up operations such as cancel, restart, and get-result.\n- [`workflow-service`](examples/inputs/workflow-service.wit): a proto-backed `SignalWithStartWorkflowExecution` example showing flattened APIs, function arguments, sourced fields, support converters, and output transforms.\n- [`type-roundtrip`](examples/inputs/type-roundtrip.wit): a proto-backed type roundtrip example for focused native/proto conversion coverage, including retry policies, activity options, durations, task queues, and priority.\n\nRebuild the checked-in example outputs:\n\n```bash\ncargo build-examples\n```\n\nRebuild one language or one example only:\n\n```bash\ncargo build-examples --lang python\ncargo build-examples --lang dotnet\ncargo build-examples user-service\ncargo build-examples --lang typescript user-service\n```\n\nRun the same validations as the CI pipeline:\n\n```bash\n./scripts/validate.sh\n```\n\nWrite the prepared WIT workspace the loader actually parses:\n\n```bash\ncargo run -- debug-wit-dir \\\n  --input examples/inputs/user-service.wit \\\n  --output /tmp/user-service-wit\n```\n\n## WIT-Direct Generation\n\nStart with a WIT file that describes the API surface directly:\n\n```wit\npackage temporal:user-service@1.0.0;\n\nworld system {\n  export user-service;\n}\n\n/// @nexus.endpoint \"__user_service\"\ninterface user-service {\n  resource user {\n    constructor(user-id: string, email: string);\n\n    update-email: func(email: string) -\u003e user-result;\n  }\n\n  record get-user-request {\n    user-id: string,\n  }\n\n  type user-result = own\u003cuser\u003e;\n\n  record update-email-request {\n    user-id: string,\n    email: string,\n  }\n\n  get-user: func(request: get-user-request) -\u003e user-result;\n  update-email: func(request: update-email-request) -\u003e user-result;\n}\n```\n\nGenerate Python:\n\n```bash\ncargo run -- generate \\\n  --lang python \\\n  --input examples/inputs/user-service.wit \\\n  --output /tmp/user_service\n```\n\nGenerate TypeScript:\n\n```bash\ncargo run -- generate \\\n  --lang typescript \\\n  --input examples/inputs/user-service.wit \\\n  --output /tmp/user-service\n```\n\nGenerate .NET:\n\n```bash\ncargo run -- generate \\\n  --lang dotnet \\\n  --input examples/inputs/user-service.wit \\\n  --output /tmp/user-service-dotnet\n```\n\nAdd `--format` to run a formatter after generation:\n\n- Python: `ruff format`\n- TypeScript: `prettier --write`\n\nThe `user-service` example is intentionally small and WIT-native. The `type-showcase` example demonstrates broader WIT type coverage: records, enums, flags, variants, results, maps, tuples, resources, resource methods, and an operation with no return value without proto annotations.\n\n## WIT Directives\n\nThe WIT file defines the public surface. `@nexus` directives carry the parts WIT does not express directly:\n\n- service endpoint names\n- service wire names\n- support file paths\n- language-native override types\n- flattened API-only field types\n- sourced field expressions\n- function conversion metadata\n- output transforms\n- explicit resource method operation bindings\n- experimental service, operation, and record warnings\n- `@nexus.delay-load-temporalio-workflow` on Python services that must not import `temporalio.workflow` until an operation executes\n\nResource methods bind to operations only when the method and operation have the same generated operation name. When they intentionally differ, mark the method with `@nexus.operation`, for example `/// @nexus.operation \"cancel-workflow\"` on `cancel: func(...)` to bind it to `cancel-workflow: func(...)`.\n\nInput WIT files can add support code with `@nexus.support`. Python support fragments are copied into the generated private `_support` package, TypeScript support fragments are emitted as `support.ts` next to the generated `index.ts`, and .NET support fragments are copied under `Support/`.\n\nSupport code can also be supplied outside WIT with repeatable `--support-file`\narguments on `generate`. Explicit support files apply to the selected\n`--lang`, are appended after WIT-declared support, and use the same generated\nlayout as `@nexus.support` fragments. .NET support files infer their support\nnamespace from the C# `namespace` declaration in the file:\n\n```bash\ncargo run -- generate \\\n  --lang python \\\n  --input examples/inputs/user-service.wit \\\n  --support-file /path/to/custom_support.py \\\n  --output /tmp/user_service\n```\n\n## Runtimes\n\nThe examples include small language runtimes that are not generated from WIT:\n\n- Python: `examples/python/nex_gen_runtime.py`\n- TypeScript: `examples/typescript/nex-gen-runtime.ts`\n\nThese runtimes provide shared serialization helpers for WIT-direct values, including the `json/nexus` payload encoding used by the example tests to round-trip generated records and resources through real Temporal Nexus clients. The TypeScript examples also include `nex-gen-payload-converter.cjs` so the Temporal TypeScript SDK can load the same payload converter through its `payloadConverterPath` data-converter hook.\n\nThese files are intentionally example/runtime shims. They should eventually be removed once the corresponding Temporal SDKs provide native serialization support for Nexus API generator values and resources.\n\n## Proto Backing\n\nProto backing is opt-in per WIT type. Use it when an operation should accept or return generated API models while converting to or from protobuf messages at the Nexus boundary.\n\nProto-backed WIT uses:\n\n- `@nexus.proto` on a WIT type to identify the protobuf message or enum it represents\n- `@nexus.proto-field` when the WIT field name differs from the proto field name\n- `--descriptors` on `generate` so the generator can validate fields and derive proto conversion code\n\nExample:\n\n```wit\npackage temporal:nexus@1.0.0;\n\nworld system {\n  export workflow-service;\n}\n\n/// @nexus.endpoint \"__temporal_system\"\n/// @nexus.service-name \"temporal.api.workflowservice.v1.WorkflowService\"\ninterface workflow-service {\n  use nexus:temporal-types/model@1.0.0.{signal-function, task-queue, workflow-function};\n\n  /// @nexus.proto \"temporal.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest\"\n  record signal-with-start-workflow-request {\n    /// @nexus.proto-field \"workflow_type\"\n    workflow: workflow-function,\n    workflow-id: string,\n    task-queue: task-queue,\n    /// @nexus.proto-field \"signal_name\"\n    signal: signal-function,\n    /// @nexus.source \"workflow_namespace\"\n    namespace: option\u003cstring\u003e,\n  }\n\n  /// @nexus.proto \"temporal.api.workflowservice.v1.SignalWithStartWorkflowExecutionResponse\"\n  record signal-with-start-workflow-response {\n    run-id: option\u003cstring\u003e,\n  }\n\n  /// @nexus.output-transform\n  ///   python-type=\"workflow.ExternalWorkflowHandle[typing.Any]\"\n  ///   python=\"workflow.get_external_workflow_handle(request.workflow_id, run_id=result.run_id)\"\n  ///   typescript-type=\"workflow.ExternalWorkflowHandle\"\n  ///   typescript=\"workflow.getExternalWorkflowHandle(request.workflowId, result.runId ?? undefined)\"\n  /// @nexus.operation name=\"SignalWithStartWorkflowExecution\"\n  signal-with-start-workflow: func(\n    request: signal-with-start-workflow-request,\n  ) -\u003e signal-with-start-workflow-response;\n}\n```\n\nGenerate a proto-backed example:\n\n```bash\ncargo run -- generate \\\n  --lang python \\\n  --input examples/inputs/workflow-service.wit \\\n  --input examples/inputs/deps \\\n  --descriptors examples/descriptors/temporal_api.bin \\\n  --output /tmp/workflow_service\n```\n\n`--descriptors` can be passed more than once when a proto-backed API depends on multiple descriptor files. Duplicate files or duplicate symbols are rejected.\n\nThe examples include a reusable Temporal semantic/common type WIT input:\n\n- `nexus:temporal-types/model@1.0.0`\n\nPass it as an additional `--input` when generating an API that uses\n`nexus:temporal-types/model@1.0.0`. For `generate`, the first `--input` is the\nAPI generation root and later inputs are linked into the parser workspace. For\n`add-rpc`, pass any WIT inputs needed to resolve shared types; when extending an\nexisting WIT file, put that file first. A linked input can be a single WIT file,\na WIT package directory, or a directory containing WIT package directories, so\n`examples/inputs/deps` links every package under it.\n\nGenerate WIT for a proto RPC from a descriptor set:\n\n```bash\ncargo run -- add-rpc \\\n  --descriptors examples/descriptors/temporal_api.bin \\\n  --rpc SignalWithStartExecution \\\n  --input examples/inputs/deps\n```\n\nWrite the standalone WIT scaffold to a file instead of stdout:\n\n```bash\ncargo run -- add-rpc \\\n  --descriptors examples/descriptors/temporal_api.bin \\\n  --rpc temporal.api.workflowservice.v1.WorkflowService.SignalWithStartWorkflowExecution \\\n  --input examples/inputs/deps \\\n  --output /tmp/add-rpc.wit\n```\n\nExtend an existing WIT file with a new RPC:\n\n```bash\ncargo run -- add-rpc \\\n  --descriptors examples/descriptors/temporal_api.bin \\\n  --rpc SignalWorkflowExecution \\\n  --input examples/inputs/workflow-service.wit \\\n  --input examples/inputs/deps\n```\n\nRewrite the existing WIT file in place by pointing `--output` at the same path:\n\n```bash\ncargo run -- add-rpc \\\n  --descriptors examples/descriptors/temporal_api.bin \\\n  --rpc SignalWorkflowExecution \\\n  --input examples/inputs/workflow-service.wit \\\n  --input examples/inputs/deps \\\n  --output examples/inputs/workflow-service.wit\n```\n\n## Validation\n\nValidate the Python examples:\n\n```bash\ncargo build-examples --lang python\ncd examples/python\nuv run pytest\nuv run basedpyright\n```\n\nValidate the TypeScript examples:\n\n```bash\ncargo build-examples --lang typescript\ncd examples/typescript\nnpm install\nnpm run test\nnpm run typecheck\n```\n\n`cargo test` validates the checked-in example outputs as-is. Use `cargo build-examples` when you want to refresh them.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftemporalio%2Fnex-gen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftemporalio%2Fnex-gen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftemporalio%2Fnex-gen/lists"}