{"id":13623329,"url":"https://github.com/samthor/kuto","last_synced_at":"2025-04-05T05:04:03.920Z","repository":{"id":228044728,"uuid":"773010026","full_name":"samthor/kuto","owner":"samthor","description":"Faster updates for big JS projects","archived":false,"fork":false,"pushed_at":"2024-04-14T22:25:24.000Z","size":189,"stargazers_count":425,"open_issues_count":4,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-04-17T19:11:03.558Z","etag":null,"topics":["javascript"],"latest_commit_sha":null,"homepage":"https://kuto.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/samthor.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-16T13:49:19.000Z","updated_at":"2024-07-23T07:02:43.468Z","dependencies_parsed_at":"2024-04-14T23:34:45.530Z","dependency_job_id":null,"html_url":"https://github.com/samthor/kuto","commit_stats":null,"previous_names":["samthor/sjs","samthor/kuto"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samthor%2Fkuto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samthor%2Fkuto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samthor%2Fkuto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samthor%2Fkuto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/samthor","download_url":"https://codeload.github.com/samthor/kuto/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247289424,"owners_count":20914464,"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":["javascript"],"created_at":"2024-08-01T21:01:30.447Z","updated_at":"2025-04-05T05:04:03.891Z","avatar_url":"https://github.com/samthor.png","language":"TypeScript","readme":"🌈 Kuto makes updating your site's JS better, faster, harder, stronger.\nIt reduces your download size by re-using code you've already shipped.\nRead more [on the blog](https://samthor.au/2024/kuto/), or watch [Theo.gg's video](https://www.youtube.com/watch?v=_sxwQBWJQHA)! 🌈\n\n\u003cimg src=\"https://storage.googleapis.com/hwhistlr.appspot.com/og/kuto.jpeg\" width=\"200\" height=\"105\" alt=\"Kuto tool logo\" /\u003e\n\n[![Tests](https://github.com/samthor/kuto/actions/workflows/tests.yml/badge.svg)](https://github.com/samthor/kuto/actions/workflows/tests.yml)\n\nIt does this by splitting JS files (in ESM) into 'main' and static parts.\nThe static parts can be cached by clients forever, as they have no side-effects, and can be used as a 'corpus' or dictionary of code that can be called later.\nChromium even caches [the bytecode](https://v8.dev/blog/code-caching-for-devs) of previously shipped files.\n\nIdeally, Kuto operates on a large output bundle from another tool.\nThink of it as doing code-splitting 'last', rather than first.\n\n## Requirements\n\nNode 16+.\n\nKuto works best on large (\u003e1mb) singular JS bundles 'bundled' to ESM — the tool works on a statement level, and an IIFE/webpack output is one giant statement.\n\n## Usage\n\nYou can install via \"kuto\" and then run `npx kuto` to learn more.\n\nTo split a JS file, you can then run:\n\n```bash\n$ kuto split yourbundle.js out/\n```\n\nThis will generate a 'main' part and a corpus of code.\nIf you build or change \"yourbundle.js\" and run Kuto _again_, this will re-use the existing corpus where possible, and remove completely disused corpus files.\n\nNote that you'll **need to keep the old generated code around** for Kuto to work.\nBy default, this looks in the output dir, but you can change it with a flag.\n\n### Flags\n\n- `-c \u003cold\u003e` where to find old corpus data (default: use output dir)\n\n  Normally, Kuto reads old corpus data from the output path, but this flag can be used to point to a different location.\n  It can also point directly to a Kuto-generated 'main' file.\n  This could be useful to point to the currently published version of your code.\n\n  For example:\n\n  - `-c https://example.com/source.js` to load a Kuto-generated 'main' from a real website (uses `fetch()`)\n  - `-c path/to/old/source/dir` to use any corpus in this dir\n\n- `-d` dedups callables (default: `false`)\n\n  With this flag enabled, if two classes or callables are exactly the same, they'll be merged into one.\n  For example:\n\n  ```ts\n  var A = class {};\n  var B = class {};\n\n  // will be 'true' in `-d` mode\n  new A() instanceof B;\n  ```\n\n  This is turned off by default, as it can be dangerous.\n  Kuto will still dedup other code where it is safe to do so!\n\n- `-m \u003cbytes\u003e` only yeet code which is larger than this (default: `32`)\n\n  There's overhead to splitting the static parts of your code out, so this limits the process to larger statements.\n\n- `-k \u003cfiles\u003e` keep this number of static bundles around (default: `4`)\n\n  Kuto can create high levels of fragmentation over time.\n  For most sites, you'll end up with one HUGE bundle that contains the bulk of your code, dependencies, etc.\n  This flag sets the number of 'corpus' files to keep around, ordered by size.\n\n  (This may not actually be the best way to keep chunks around.\n  This flag will probably evolve over time.)\n\n- `-n \u003cname\u003e` use this basename for the output (default: basename of input)\n\n  Normally, Kuto creates output files with the same name as the input files.\n  Instead, use this to output e.g., \"index.js\" regardless of source name.\n\n## Best Practice\n\nOne good way to understand what Kuto does is to run `./release.sh`, which builds Kuto itself.\nTry running a release, changing something in the source, and releasing again\u0026mdash;you'll see extra static files appear.\n\nThis release process runs in three steps:\n\n1. use esbuild to create one bundle (without minification)\n2. use kuto to split the bundle\n3. use esbuild on all resulting files, _purely_ to minify\n\n## Notes\n\nKuto bundles [acorn](https://www.npmjs.com/package/acorn) to do its parsing.\n\nThere is also has a `kuto info` command to give basic information about an ES Module.\nThis is the origin of the tool; I wanted something that could inform me about side-effects.\n\nBoth `info` and `split` will transparently compile TS/etc via \"esbuild\" if installed, but it's not a `peerDependency`.\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamthor%2Fkuto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamthor%2Fkuto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamthor%2Fkuto/lists"}