{"id":16517850,"url":"https://github.com/erhant/thuffscript","last_synced_at":"2025-10-28T06:32:13.999Z","repository":{"id":204277039,"uuid":"690720777","full_name":"erhant/thuffscript","owner":"erhant","description":"Write Huff without ever leaving TypeScript.","archived":true,"fork":false,"pushed_at":"2024-09-19T17:38:36.000Z","size":238,"stargazers_count":8,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-10T04:23:47.090Z","etag":null,"topics":["evm","huff","solidity","types","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/thuffscript","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/erhant.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":null,"security":null,"support":null,"governance":null}},"created_at":"2023-09-12T18:31:32.000Z","updated_at":"2024-09-19T17:38:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"407f9a73-ed70-4b0e-bfc0-d9b01f0b0f8f","html_url":"https://github.com/erhant/thuffscript","commit_stats":null,"previous_names":["erhant/thuffscript"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erhant%2Fthuffscript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erhant%2Fthuffscript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erhant%2Fthuffscript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erhant%2Fthuffscript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erhant","download_url":"https://codeload.github.com/erhant/thuffscript/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238607791,"owners_count":19500254,"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":["evm","huff","solidity","types","typescript"],"created_at":"2024-10-11T16:33:59.701Z","updated_at":"2025-10-28T06:32:13.612Z","avatar_url":"https://github.com/erhant.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ch1 align=\"center\"\u003e\n    \u003ccode\u003ethuffscript\u003c/code\u003e\n  \u003c/h1\u003e\n\n  \u003cdiv align=\"center\"\u003e\n      \u003ca href=\"https://www.npmjs.com/package/thuffscript\" target=\"_blank\"\u003e\n        \u003cimg alt=\"NPM\" src=\"https://img.shields.io/npm/v/thuffscript?logo=npm\u0026color=CB3837\"\u003e\n      \u003c/a\u003e\n      \u003ca href=\"./.github/workflows/tests.yml\" target=\"_blank\"\u003e\n          \u003cimg alt=\"Workflow: Tests\" src=\"https://github.com/erhant/thuffscript/actions/workflows/tests.yaml/badge.svg?branch=main\"\u003e\n      \u003c/a\u003e\n      \u003ca href=\"https://opensource.org/licenses/MIT\" target=\"_blank\"\u003e\n          \u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/badge/license-MIT-blue.svg\"\u003e\n      \u003c/a\u003e\n  \u003c/div\u003e\n\n  \u003cp align=\"center\"\u003e\n    \u003ci\u003eWrite Huff without ever leaving TypeScript.\u003c/i\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\u003e [!CAUTION]\n\u003e\n\u003e With [Huff](https://github.com/huff-language/huff-rs) being archived, we've put this to sleep as well. 💤\n\n## Install\n\nInstall the package via:\n\n```sh\nyarn add     thuffscript # yarn\nnpm  install thuffscript # npm\npnpm add     thuffscript # pnpm\nbun  add     thuffscript # bun\n```\n\n## Usage\n\nThuffscript exposes a class for each Huff construct:\n\n- `Macro` and `Fn` is used to write macros and functions.\n\n  - `Main` and `Constructor` classes are also exported as a shorthand.\n  - Instructions are type-safe, we only allow opcodes or other Huff constructs.\n  - If the macro has arguments, TypeScript automatically allows `\u003carg-name\u003e` within the instruction.\n  - To get the macro size, use `macro.size` property.\n  - To call a macro, use `macro.call()` function with the necessary arguments.\n\n- `Test` is similar to `Macro`, but can accept a `calldata` and `value` for the test.\n\n- `Label` is used to create jump labels. Each label object exports a jump source (`label.src`) and destination (`label.dest`) which can be used within a macro.\n\n- `Constant` is used to define constant values.\n\n  - Use `FreeStoragePointer` for the free storage pointer constants.\n\n- `FunctionABI` and `EventABI` is used to describe a function interface and event interface.\n\n  - A function interface also has a `function.label` property, which is a shorthand to create a `Label` for this function.\n\n- `ErrorABI` is used to describe a custom error.\n\n- `CodeTable`, `JumpTable` and `PackedJumpTable` are used to create tables.\n\n### Compiling to Huff\n\nFinally, a `Program` class is exported, which is what you will be using to compile all this to a Huff program. You can provide macros, functions, and tests to a program, and all of these, including the macros that have been used within them, will be compiled!\n\nYou can then call `program.compile` with optional metadata such as license, authors, etc. which will compile everything and assign it to `program.code` field. You can use `program.export` to export that code at some path.\n\n\u003e [!NOTE]\n\u003e\n\u003e **Thuffscript is not a tool to test or deploy Huff contracts**! You should simply use this to write \u0026 compile to Huff; the tests can be done via Foundry or Hardhat as is the case usually.\n\u003e\n\u003e Nevertheless, contributions are welcome for such integrations. :)\n\n### Writing a Macro\n\nWhen you are writing a macro (or a test, or a function), you provide the instructions (i.e. body of the macro) not to the constructor, but to the `body` function right after creating the object. This provides a nice type-safety when there are arguments for the macro.\n\nThe `body` function accepts arbitrarily many arguments, and each argument can be a single statement or an array of statements:\n\n- Each argument corresponds to a line.\n- Multiple statements within a single argument will be written to the same line.\n- An empty array as an argument corresponds to an empty line.\n\nHere is an example macro from SimpleStore:\n\n```ts\nconst VALUE_LOCATION = new FreeStoragePointer('VALUE_LOCATION');\n\n// ...\n\nconst GET_VALUE = new Macro('GET_VALUE').body(\n  // load value from storage\n  VALUE_LOCATION,\n  'sload',\n  [],\n  // store value in memory\n  [0x00, 'mstore'],\n  [],\n  // return value\n  [0x20, 0x00, 'return']\n);\n```\n\nThis results in the following Huff code:\n\n```c\n#define constant VALUE_LOCATION = FREE_STORAGE_POINTER()\n\n// ...\n\n#define macro GET_VALUE() = takes(0) returns(0) {\n    [VALUE_LOCATION]\n    sload\n\n    0x0 mstore\n\n    0x20 0x0 return\n}\n```\n\n## Examples\n\nSeveral examples are provided under the [examples](./examples/) folder. You can run them via:\n\n```sh\nbun run eg:\u003cexample-name\u003e\n```\n\n## Testing\n\nAfter cloning the repo, install dependencies:\n\n```sh\nbun install\n```\n\nThen, run the tests:\n\n```sh\nbun test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferhant%2Fthuffscript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferhant%2Fthuffscript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferhant%2Fthuffscript/lists"}