{"id":21533297,"url":"https://github.com/alinz/ella","last_synced_at":"2026-04-02T01:58:12.977Z","repository":{"id":142955423,"uuid":"591489429","full_name":"alinz/ella","owner":"alinz","description":"yet another IDL for generating proper RPC for golang client/server and other languages","archived":false,"fork":false,"pushed_at":"2024-07-08T14:55:45.000Z","size":363,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-18T16:02:56.438Z","etag":null,"topics":["generator","golang","rpc","typescript","workflow"],"latest_commit_sha":null,"homepage":"https://compiler.ella.to","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alinz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2023-01-20T22:08:27.000Z","updated_at":"2024-07-08T14:55:49.000Z","dependencies_parsed_at":"2024-02-23T21:26:10.472Z","dependency_job_id":"5a19850d-6dfd-4953-859e-20e304b777fb","html_url":"https://github.com/alinz/ella","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alinz%2Fella","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alinz%2Fella/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alinz%2Fella/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alinz%2Fella/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alinz","download_url":"https://codeload.github.com/alinz/ella/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243165500,"owners_count":20246722,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["generator","golang","rpc","typescript","workflow"],"created_at":"2024-11-24T02:28:09.818Z","updated_at":"2025-12-26T05:09:59.928Z","avatar_url":"https://github.com/alinz.png","language":"Go","readme":"```\n┌─┐┬  ┬  ┌─┐\n├┤ │  │  ├─┤\n└─┘┴─┘┴─┘┴ ┴ v0.0.2\n```\n\nElla, is yet another compiler to produce Go and Typescript code based on simple and easy-to-read schema IDL. There are many tools like gRPC, Twirp or event WebRPC to generate codes, but this little compiler is designed based on my views of 10+ years of developing backend and APIs. I wanted to simplify the tooling and produce almost perfect optimized, handcrafted code that can be read and understood, not like the output of gRPC.\n\nElla's schema went through several iterations to make it easier for extension and backward compatibility in future releases.\n\n\u003e **NOTE:**\n\u003e\n\u003e Ella's code generated has been used in couple of production projects, it has some designs that might not fit your needs, but I think it might solve a large number of projects. Also Ella's only emit `Go`, as a server and client, and `Typescript` as only client. This is intentinal as it servers my needs. However it can be extetended to produce other languages code by traversing the AST code.\n\n# Installation\n\nto install Ella's compiler, simply use the go install command\n\n```bash\ngo install compiler.ella.to@latest\n```\n\n# Usage\n\nSimplicity applies to the CLI command as well, it looks for all files that need to be compiled and outputs the result to the designated file. The extension of the output file tells the compiler whether you want to produce the typescript or golang code. That's pretty much of it.\n\nFor example, the following command, will generate `api.gen.go` in `/api` folder with the package name `api` and will read all the ella files inside `./schema` folder.\n\n```bash\nella gen api /api/api.gen.go ./schema/*.ella\n```\n\nAlso, we can format the schema as well to have a consistent look by running the following command\n\n```bash\nella fmt ./schema/*.ella\n```\n\nThe full CLI documentation can be accessed by running Ella command without any arguments\n\n```\n┌─┐┬  ┬  ┌─┐\n├┤ │  │  ├─┤\n└─┘┴─┘┴─┘┴ ┴ v0.0.2\n\nUsage: ella [command]\n\nCommands:\n  - fmt Format one or many files in place using glob pattern\n        ella fmt \u003cglob path\u003e\n\n  - gen Generate code from a folder to a file and currently\n        supports .go and .ts extensions\n        ella gen \u003cpkg\u003e \u003coutput path to file\u003e \u003csearch glob paths...\u003e\n\n  - ver Print the version of ella\n\nexample:\n  ella fmt ./path/to/*.ella\n  ella gen rpc ./path/to/output.go ./path/to/*.ella\n  ella gen rpc ./path/to/output.ts ./path/to/*.ella ./path/to/other/*.ella\n```\n\n# Schema\n\nThere is a simple role when writing a schema in Ella's IDL, all identifier needs to be `Pascal Case`. This eliminates colliding with reserved keywords.\n\n## const\n\nA constant is a value that is immutable and can be used in field and method options.\n\n### int\n\n```\nconst BuildNumber = 10\n```\n\n### float\n\n```\nconst Pi = 3.14\n```\n\n### string\n\n```\nconst DoubleQuote = \"1.0.0\"\n\nconst SingleQuote = 'Hello World'\n\nconst MultiLine = `Hello\n  This is really cool\n\n  bye\n`\n```\n\n### bool\n\n```\nconst Debug = true\n```\n\n### byte size\n\nThis is a very helpful time as it makes it easier to write values in bytes type. The following postfixes can be used: `b`, `kb`, `mb`, `gb`, `tb`, `pb`, `eb`\n\n\u003e Note: the number has to be integer. No floating is premitted. In order to represent `1.1kb`, use the lower postfix `b` and represent the number as follows: `1100b`.\n\n```\nconst MaxFileUploadSize = 100mb\n```\n\n### duration\n\n\u003e Note: `duration` type is also the same as `byte size` type. Only interger value is permitted.\n\nThis is a very helpful time as it makes it easier to write values in duration type. The following postfixes can be used: `ns`, `us`, `ms`, `s`, `m`, `h`\n\n```\nconst MaxWaitTime = 5h\n```\n\n## enum\n\n`enum` is a way to define a series of const values under the same category. In Golang, there is no such thing as `enum` and usually, people use a custom type and assign values to it. Ella's compiler does the heavy lifting of that and generates the most optimized version of the Go representation that supports both `yaml` and `json` marshal and unmarshal operations. It also supports ignoring value using `_` keyword.\n\n\u003e Note: Ella's enum type doesn't have a type, because behind the scene it will generate approporate type which is most memory efficient and optimize.\n\n```\nenum UserType {\n  _\n  Normal\n  Guest\n  Root\n}\n\nenum UserStatus {\n  _\n  Active = 10\n  Deactive\n  Deleted = 65\n}\n```\n\n## model\n\nmodel is a way to define a series of variables under the same category, similar to `struct` in Go.\n\n```\nmodel User {\n  Firstname: string\n  Lastname: string\n  Age: int8\n  LocationMap: []string\n  Parents: []User\n  ComplexMap: map\u003cstring, []User\u003e\n  CreatedAt: timestamp\n}\n```\n\n\u003e Note: Model's field type can be any of the default types such as `byte`, `bool`, `int8`, `int16`, `int32`, `int64`, `uint8`, `uint16`, `uint32`, `uint64`, `float32`, `float64`, `timestamp`, `string`, and complex types such as `map\u003ckey, value\u003e` and array `[]type`, or it can be any other model's or enum's name type.\n\n### field options\n\nfield options is a way to customize and assign values to each field of the model. Currently, there are the following predefined field options available.\n\n- JsonOmitEmpty\n\nis a boolean value that adds `omitempty` inside `Go` generated struct tag.\n\n```\nmodel User {\n  Username: string\n  Password: string {\n    JsonOmitEmpty = true\n  }\n}\n```\n\nSo basically the above model generates a `Go` struct as follows:\n\n```golang\ntype User struct {\n  Username string `json:\"username\"`\n  Password string `json:\"password,omitempty\"`\n}\n```\n\n- Json\n\nJson option fields are a way to either not marshal and unmarshal the value or renaming the field during marshal and unmarshal operations.\n\n```\nmodel User {\n  Firstname: string {\n    Json = \"firstName\"\n  }\n}\n\nmodel AnotherUser {\n  Username: string\n  Password: string {\n    Json = false\n  }\n}\n```\n\nThe above model will be converted to the following `Go` code\n\n```Golang\ntype User struct {\n  Firstname string `json:\"firstName\"`\n}\n\ntype AnotherUser struct {\n  Username string `json:\"username\"`\n  Password string `json:\"-\"`\n}\n```\n\n- Yaml\n\nis the same as `Json`. Currently, this is the only option available for `Yaml`.\n\n```\nmodel User {\n  Firstname: string {\n    Yaml = \"firstName\"\n  }\n}\n\nmodel User {\n  Username: string\n  Password: string {\n    Yaml = false\n  }\n}\n```\n\n## service\n\n### http\n\n#### stream\n\n#### file upload\n\n### rpc\n\n### method options\n\n### error\n\nDefining custom errors\n\n```\nerror ErrUserNotFound { Code = 1000 HttpStatus = NotFound Msg = \"user not found\" }\n```\n\nhttp status can be one of the following values\n\n- Continue: 100\n- SwitchingProtocols: 101\n- Processing: 102\n- EarlyHints: 103\n- OK: 200\n- Created: 201\n- Accepted: 202\n- NonAuthoritativeInfo: 203\n- NoContent: 204\n- ResetContent: 205\n- PartialContent: 206\n- MultiStatus: 207\n- AlreadyReported: 208\n- IMUsed: 226\n- MultipleChoices: 300\n- MovedPermanently: 301\n- Found: 302\n- SeeOther: 303\n- NotModified: 304\n- UseProxy: 305\n- TemporaryRedirect: 307\n- PermanentRedirect: 308\n- BadRequest: 400\n- Unauthorized: 401\n- PaymentRequired: 402\n- Forbidden: 403\n- NotFound: 404\n- MethodNotAllowed: 405\n- NotAcceptable: 406\n- ProxyAuthRequired: 407\n- RequestTimeout: 408\n- Conflict: 409\n- Gone: 410\n- LengthRequired: 411\n- PreconditionFailed: 412\n- RequestEntityTooLarge: 413\n- RequestURITooLong: 414\n- UnsupportedMediaType: 415\n- RequestedRangeNotSatisfiable: 416\n- ExpectationFailed: 417\n- Teapot: 418\n- MisdirectedRequest: 421\n- UnprocessableEntity: 422\n- Locked: 423\n- FailedDependency: 424\n- TooEarly: 425\n- UpgradeRequired: 426\n- PreconditionRequired: 428\n- TooManyRequests: 429\n- RequestHeaderFieldsTooLarge: 431\n- UnavailableForLegalReasons: 451\n- InternalServerError: 500\n- NotImplemented: 501\n- BadGateway: 502\n- ServiceUnavailable: 503\n- GatewayTimeout: 504\n- HTTPVersionNotSupported: 505\n- VariantAlsoNegotiates: 506\n- InsufficientStorage: 507\n- LoopDetected: 508\n- NotExtended: 510\n- NetworkAuthenticationRequired: 511\n\n# References\n\n- Here is the list of reserved keywords:\n\n  - const\n  - enum\n  - model\n  - http\n  - rpc\n  - service\n  - byte\n  - bool\n  - int8\n  - int16\n  - int32\n  - int64\n  - uint8\n  - uint16\n  - uint32\n  - uint64\n  - float32\n  - float64\n  - timestamp\n  - string\n  - map\n  - any\n  - file\n  - stream\n  - error\n\n- The logo was generated [here](https://patorjk.com/software/taag/#p=display\u0026f=Calvin%20S\u0026t=ella)\n\n```\n\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falinz%2Fella","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falinz%2Fella","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falinz%2Fella/lists"}