{"id":18472692,"url":"https://github.com/gregros/zenesis","last_synced_at":"2026-02-27T12:05:50.661Z","repository":{"id":195770666,"uuid":"693609426","full_name":"GregRos/zenesis","owner":"GregRos","description":"Revolutionary generator for type declarations.","archived":false,"fork":false,"pushed_at":"2025-05-04T21:13:42.000Z","size":7338,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-06T02:41:33.898Z","etag":null,"topics":["code-generation","framework","functional-programming","incomplete","interesting","javascript","package","type-declarations","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/GregRos.png","metadata":{"files":{"readme":null,"changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-19T11:15:18.000Z","updated_at":"2025-05-06T13:07:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"89e6c960-4f2e-4aeb-bb00-a7e3f6fe1be6","html_url":"https://github.com/GregRos/zenesis","commit_stats":null,"previous_names":["gregros/zenesis"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/GregRos/zenesis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregRos%2Fzenesis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregRos%2Fzenesis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregRos%2Fzenesis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregRos%2Fzenesis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GregRos","download_url":"https://codeload.github.com/GregRos/zenesis/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregRos%2Fzenesis/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29893716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T09:48:51.284Z","status":"ssl_error","status_checked_at":"2026-02-27T09:48:43.992Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["code-generation","framework","functional-programming","incomplete","interesting","javascript","package","type-declarations","typescript"],"created_at":"2024-11-06T10:21:50.225Z","updated_at":"2026-02-27T12:05:50.653Z","avatar_url":"https://github.com/GregRos.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zenesis\n`zenesis` is a game-changing library for **generating type definitions** using `zod`-compatible schemas.\n\n![[Zenesis Schema.svg]]\n\n✏️ Write type generation code that kind of looks like the code being generated!\n\n😌 No messing around with syntax trees or strange compiler APIs!\n\n🧠 Your type schemas are statically validated as you type!\n\n🛠️ Supports almost every single type system construct, including advanced generic types!\n\n📘 Document every single one!\n\n🛡️ Automatically get a `zod` schema to validate the types you're generating!\n\n`zenesis` is extremely powerful and *might be overwhelming for novices*. Which is why you can use it to build your own code generation tools!\n## Install\n```bash\nnpm install zod zenesis\n```\n\n## Design\n`zenesis` wouldn't be possible without `zod`, and it builds on it by expanding schemas to include almost all type system constructs, with very few exceptions. \n\nEvery `zenesis` schema that describes a type behaves at runtime like a `zod` schema with an equivalent structure, and the generated type is going to be behaviorally equivalent to the inferred type (that is, the result of `z.infer\u003cZenesisType\u003e`). This means that you can test out how the generated types will work by doing something like:\n\n```typescript\nconst x: z.infer\u003ctypeof ZenesisSchema\u003e = null!\n\nx.expectedMethod()\nx.callSomething(42, \"should be legal\")\n```\n\nThe trick is that the type of `x` will be an ungodly monstrosity completely illegible to humans, whereas the generated code is going to be cleaner than what most developers write.\n\nThis close correspondence means you can just test out how your generated code will work by using `z.infer`. Of course if you want to use the full power of the library, you would do entirely dynamic seat-of-your-pants code generation. \n\n\n\n\n\n`zenesis` is incredibly similar to `zod` in many ways\n## Example\n`zenesis`\n```typescript\n// import { z } from \"zod\"\n// ↑ not needed, all relevant zod schemas are-exported by zenesis.\n//   mixing the two is totally fine, however.\nimport {zs} from \"zenesis\"\n\n// A container for files. One of the few mutable objects.\nconst world = zs.world()\n\n// This both creates a file object and embeds it in the `world`.\n// Takes the name of the file (excluding extensions) and a \n// builder function.\nconst personFile = world.file(\"person\", function*(file) {\n\t// Construct declarations, which are also validation schemas.\n\t// Declaration schemas are statically validated.\n\tconst person = file.interface(\"Person\", {\n\t\t// Declare a field:\n\t\tname: zs.field(\n\t\t\t// The type of the field\n\t\t\tzs.string()\n\t\t).describe(\n\t\t\t// This will be inserted into the generated code via JSDoc\n\t\t\t\"The person's name\"\n\t\t// Supports modifiers like readonly:\n\t\t).readonly(),\n\t\t\n\t\t// Another field declaration:\n\t\tage: zs.field(\n\t\t\tzs.number()\n\t\t).describe(\"The person's age\").readonly(),\n\t\t\n\t\t// A method declaration, complete with documentation:\n\t\tgreet: zs.method(\n\t\t\t// These are arguments.\n\t\t\tzs.lazy(() =\u003e person).describe(\n\t\t\t\t// The parameter's name is extracted from the documentation.\n\t\t\t\t\"person: The person to greet\"\n\t\t\t)\n\t\t).returns(\n\t\t\tzs.boolean().describe(\n\t\t\t\t// Documenting the return value is also supported.\n\t\t\t\t\"Whether the person was greeted.\"\n\t\t\t)\n\t\t).describe(\n\t\t\t// The method's documentation.\n\t\t\t\"Greets a person.\"\n\t\t)\n\t\t\n\t}).describe(\n\t\t// The interface's documentation:\n\t\t\"Represents a person\"\n\t)\n\t// Using yield will export a declaration.\n\t// If we didn't do this, and referenced the declaration from somewhere else,\n\t// it would be written to the file without being exported.\n\tyield person\n})\n\n// Exported declarations are available on the file object.\n// Yes, this is still statically typed. You can even use zod's\n// infer.\nconst person: zs.infer\u003ctypeof personFile.Person\u003e = personFile.Person.parse({\n\tname: \"greg\",\n\tage: 34,\n\tgreet(person) {\n\t\tconsole.log(`Hi ${person.name}!`)\n\t\treturn true\n\t}\n})\n\n// We can write the whole set of generated files to a specific path.\n// For multiple files with interdependent types, import statements\n// will be generated automatically.\n// Formatted using Prettier.\nworld.writeSync(\"../generated\")\n```\n\nThe above code generates the file:\n```typescript\n// FILE: person.d.ts\n\n/**\n * Represents a person\n */\nexport declare interface Person {  \n\t/** The person's name */\n    readonly name: string;  \n  \n\t/** The person's age */\n    readonly age: number;  \n\t\n\t/**\n\t * Greets a person.\n\t * @param person The person to greet.\n\t * @returns Wether the person was greeted.\n\t */\n\tgreet(person: Person): boolean\n}\n```\n## How it works\n`zenesis` builds on `zod`'s validation schemas, adding schema nodes representing things such as:\n\n* Classes, interfaces, and type aliases\n* Fields and methods, including overloads\n* Static members\n* Conditional types, generic types, mapped types \n* Generic function types\n* Type-level operators such as `keyof` and `typeof`\n* Modules, exports and imports\n\nSchemas are statically validated to the maximum possible extent, making sure the code you're generating will be free of syntax and semantic errors. \n\nThat said, some kinds of schemas can't be validated statically due to various **limitations** (see below), and in some cases you might have to discard type annotations in favor of dynamically constructing schemas.\n\n## Limitations\n`zenesis` has a number of limitations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregros%2Fzenesis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgregros%2Fzenesis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregros%2Fzenesis/lists"}