{"id":13494011,"url":"https://github.com/rsms/estrella","last_synced_at":"2025-05-15T02:01:58.155Z","repository":{"id":41879499,"uuid":"265972224","full_name":"rsms/estrella","owner":"rsms","description":"Lightweight and versatile build tool based on the esbuild compiler","archived":false,"fork":false,"pushed_at":"2024-06-16T13:48:32.000Z","size":1384,"stargazers_count":1099,"open_issues_count":21,"forks_count":38,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-05-07T21:13:54.266Z","etag":null,"topics":["compiler","esbuild","javascript","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rsms.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2020-05-21T23:20:55.000Z","updated_at":"2025-04-27T23:31:34.000Z","dependencies_parsed_at":"2024-09-25T00:03:08.824Z","dependency_job_id":null,"html_url":"https://github.com/rsms/estrella","commit_stats":{"total_commits":206,"total_committers":8,"mean_commits":25.75,"dds":0.03398058252427183,"last_synced_commit":"aca6a68104cdc35c9112d3a559840e38fdc1a12a"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2Festrella","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2Festrella/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2Festrella/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsms%2Festrella/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rsms","download_url":"https://codeload.github.com/rsms/estrella/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254259363,"owners_count":22040815,"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":["compiler","esbuild","javascript","typescript"],"created_at":"2024-07-31T19:01:20.891Z","updated_at":"2025-05-15T02:01:58.081Z","avatar_url":"https://github.com/rsms.png","language":"TypeScript","readme":"\u003cimg src=\"misc/estrella-logo.png\" width=\"320\" align=\"center\"\u003e\n\nEstrella is a lightweight and versatile build tool based on the fantastic\n[esbuild](https://github.com/evanw/esbuild) TypeScript and JavaScript compiler.\n\n- Rebuild automatically when source files change\n- Build multiple projects at once, in parallel\n- TypeScript diagnostics run in parallel\n- TypeScript diagnostics are optional even for TypeScript projects\n- Ability to remap TSXXXX TypeScript diagnostic severity levels, for example to\n  treat some issues as warnings instead of errors\n- Scriptable — run any JavaScript you want as part of your build process\n- Can run your program automatically when it's rebuilt\n- [Well-tested](https://github.com/rsms/estrella/tree/master/test) code\n- Fast!\n\nSee [estrella.d.ts](estrella.d.ts) for API documentation.\n\nEstrella tries hard to retain the blazing startup speed of esbuild.\nBeing just a single file, with only a dependency on esbuild,\nestrella starts very quickly.\n`time estrella -help` completes in about 50ms with NodeJS 12.\nBuilding a simple example with `time examples/minimal/build.js` completes in about 65ms.\n\nUnlike some other \"builders\" Estrella does not use a config file or require you to make changes\nto your package.json file. Instead, Estrella recognizes \u0026 embraces the fact that most projects\nhave unique build requirements. You run Estrella from a script (instead of Estrella running a\nscript or config file.) Essentially you create a \"build.js\",\nor lolcat.js—name it whatever you want—script in which you invoke estrella. This turns your script\ninto a fully-featured CLI program with access to a\n[rich API exposed by the estrella module](estrella.d.ts).\n\n\n## Example use\n\n1. Add Estrella to your project: `npm install -D estrella`\n2. Create a `build.js` file in your project directory:\n\n```js\n#!/usr/bin/env node\nconst { build } = require(\"estrella\")\nbuild({\n  entry: \"src/main.ts\",\n  outfile: \"out/foo.js\",\n  bundle: true,\n  // pass any options to esbuild here...\n})\n```\n\nInvoke your build script: (assumes `chmod +x build.js` has been set)\n\n```txt\n$ ./build.js -watch\nWrote out/foo.js (419 bytes, 6.84ms)\nWatching files for changes...\n```\n\nAnd that's it for basic use.\n\n[See the `examples` directory](examples) for more examples\nwhich you can use as templates for new projects.\n\nSee [evanw/esbuild/lib/shared/types.ts](https://github.com/evanw/esbuild/blob/master/lib/shared/types.ts)\nfor documentation of esbuild options.\n\n\n## TypeScript diagnostics\n\nIf there is a tsconfig.json file in the project directory,\nor if `build({tsc:true})` is set,\nTypeScript's `tsc` is run in parallel to esbuild, checking types and providing diagnostics:\n\n```txt\n$ ./build.js\nWrote out/foo.js (419 bytes, 7.11ms)\nsrc/main.ts:2:7 - warning TS6133: 'count' is declared but its value is never read.\n\n2   let count = 4\n        ~~~~~\n\nTS: OK   1 warning\n```\n\nWhat `tsc` program is run? estrella will ask nodejs to find typescript in node_modules.\nIf found, `tsc` from that package is used. Otherwise, `tsc` from the environment PATH is used.\nThis way there is no hard dependency on typescript for estrella.\n\nestrella allows remapping the severity of TypeScript diagnostics and even filtering\nthings out completely.\nThis is particularly useful when you are converting a codebase to a stricter set of rules\nbut don't want your build to fail. For example, let's say that you enable `noImplicitAny` in\nyour tsconfig.json file. If you just run `tsc` on your project, it will fail with errors.\nUsing estrella these errors can be treated as warnings instead, still making a loud\nappearance on screen but not causing an error exit code.\n\n```txt\n$ ./build.js\nWrote out/foo.js (14.6kb, 11.07ms)\nsrc/main.ts:212:24 - error TS7006: Parameter 'ev' implicitly has an 'any' type.\n\n212   window.onmousemove = ev =\u003e { grid.origin = [ev.clientX, ev.clientY] }\n                           ~~\nTS: 1 error\n$ echo $?\n1\n```\n\nTo make this a warning, add a rule to `build()` in your build script:\n\n```js\n#!/usr/bin/env node\nconst { build } = require(\"estrella\")\nbuild({\n  entry: \"src/main.ts\",\n  outfile: \"out/foo.js\",\n  bundle: true,\n  tsrules: {\n    7006: \"WARNING\",\n  }\n})\n```\n\nNow if we try to build again:\n\n```txt\n$ ./build.js\nWrote out/foo.js (14.6kb, 10.42ms)\nsrc/main.ts:212:24 - warning TS7006: Parameter 'ev' implicitly has an 'any' type.\n\n212   window.onmousemove = ev =\u003e { grid.origin = [ev.clientX, ev.clientY] }\n                           ~~\nTS: OK   1 warning\n$ echo $?\n0\n```\n\nThe program exits successfully while still logging the issue.\n\n`tsrules` is an object of type `{ [tscode:number] : \"IGNORE\"|\"INFO\"|\"WARN\"|\"ERROR\" }` which\nmaps TS diagnostic codes to:\n\n- `\"IGNORE\"` completely ignore and don't even log it.\n- `\"INFO\"` log it as information, unless the -quiet flag is set.\n- `\"WARN\"` log it as a warning\n- `\"ERROR\"` log it as an error, causing the program's exit code to be !0.\n\n`\"ERROR\"` is the default for most issues.\nToo list predefined tsrules, run: `node -p 'require(\"estrella\").defaultTSRules'`.\nRules which you provide take precedence, so if there are any predefined rules you'd\nlike to change, simply set those in your `tsrules` object.\n\nIn case you need to disable TypeScript diagnostics for a project with a tsconfig.json\nfile, you can set `tslint:false` in your build config:\n\n```js\nbuild({\n  // your regular options ...\n  tslint: false,\n})\n```\n\n\n## Examples and feature documentation\n\n\n### Your build script becomes a CLI program\n\nWhen using estrella as a library from a build script, your build script becomes a program\nwith command-line options:\n\n```txt\n$ ./build.js -help\nusage: ./build.js [options]\noptions:\n  -w, -watch         Watch source files for changes and rebuild.\n  -g, -debug         Do not optimize and define DEBUG=true.\n  -r, -run           Run the output file after a successful build.\n  -sourcemap         Generate sourcemap.\n  -inline-sourcemap  Generate inline sourcemap.\n  -no-color          Disable use of colors.\n  -no-clear          Disable clearing of the screen, regardless of TTY status.\n  -no-diag           Disable TypeScript diagnostics.\n  -color             Color terminal output, regardless of TTY status.\n  -diag              Only run TypeScript diagnostics (no esbuild.)\n  -quiet             Only log warnings and errors but nothing else.\n  -silent            Don't log anything, not even errors.\n  -estrella-version  Print version of estrella and exit 0.\n  -estrella-debug    Enable debug logging of estrella itself.\n```\n\nYou can define your own custom CLI options and parse arbitrary arguments using the `cliopts` object\nexported by the estrella module:\n\n```js\n#!/usr/bin/env node\nconst { build, cliopts, file } = require(\"estrella\")\nconst [ opts, args ] = cliopts.parse(\n  [\"c, cat\" , \"Prints a nice cat.\"],\n  [\"file\"   , \"Show contents of \u003cfile\u003e.\", \"\u003cfile\u003e\"],\n)\nopts.cat \u0026\u0026 console.log(stdoutStyle.pink(ASCII_cat))\nif (opts.file) {\n  console.log(`contents of file ${opts.file}:`)\n  console.log(await file.read(opts.file, \"utf8\"))\n}\nbuild({ ... })\n```\n\nAsk for help to see your options documented:\n\n```\n./build.js -h\nusage: ./build.js [options]\noptions:\n  [...common estrella options here...]\n  -c, -cat           Prints a nice cat.\n  -file=\u003cfile\u003e       Show contents of \u003cfile\u003e.\n```\n\nFor a full example, see [examples/custom-cli-options](examples/custom-cli-options)\n\n\n\n### Watching source files for changes\n\nOne of the key features of Estrella is its ability to watch source files for changes and rebuild\nonly the products needed. It does this in cooperation with esbuild which provides \"perfect\"\ninformation about the source file graph for a given build product (via esbuild.metafile).\nEstrella then uses this information to watch the relevant source files for changes and trigger a\nrebuild. Either set `watch` in your config or pass `-watch` on the command line:\n\n```\n$ ./build.js -watch\nWrote out/main.js (341B, 8.03ms)\nWatching files for changes...\n\n# [make an edit to a source file]\n1 file changed: foo.ts\nWrote out/main.js (341B, 10.18ms)\n...\n```\n\n\n### Running your program\n\nEstrella can run and manage sub processes, making it easy to run and restart your program\nupon a successful build. Simply set `run` in your config or pass `-run` on the command line:\n\n```\n$ ./build.js -run\nHello world\n```\n\nCombining `-run` with `-watch` makes for a powerful \"exploratory programming\" setup where\nchanges to your source files are compiled and the results of running the program shown.\n\n```\n$ ./build.js -watch -run\nWrote out/main.js (341B, 8.21ms)\nRunning out/main.js [98609]\nHello world\nout/main.js exited (0)\n\n# [make an edit to a source file]\n1 file changed: message.ts\nWrote out/main.js (341B, 8.21ms)\nRunning out/main.js [98609]\nHello future\n```\n\nEstrella is good at handling processes and can make a few valuable guarantees:\n\n- A running process is always terminated before Estrella terminates.\n  The only exception to this is if the estrella process is killed with an uncapturable signal\n  like SIGKILL.\n- A running process that is restarted is always terminates before a new instance is launched.\n  This is important if your program relies on exclusive access to resources like TCP ports or\n  UNIX sockets.\n- Secondary subprocesses spawned by a running process are always terminated when the process\n  Estrella controls is terminated. This guarantee only applies to OSes that support signaling\n  process groups (most POSIX OSes like Linux, macOS, BSD, etc.)\n\n\"run\" can be configured to run arbitrary commands by specifying `run` in your config.\n\nExamples: (effective process invocation in comment)\n\n```js\n// build config               // effective program invocation\nrun: true                     // [node, outfile] (same as `-run` on the command line)\nrun: [\"deno\", \"file name.js\"] // [\"deno\", \"file name.js\"]\nrun: \"./prettier foo.js\"      // runs script \"./prettier foo.js\" in a shell\n```\n\nWhen `run` is set in your config, the product will be run no matter how you invoke your build\nscript. If you want to execute a more complex command that just `node outfile` while still\nonly running it when `-run` is passed on the command line, conditionally enable `run` in your\nbuild script like this:\n\n```js\n#!/usr/bin/env node\nconst { build, cliopts } = require(\"estrella\")\nconst p = build({\n  entry: \"main.ts\",\n  outfile: \"out/main.js\",\n  run: cliopts.run \u0026\u0026 [\"/bin/zsh\", \"-e\", \"-c\", \"echo **/*.ts\"],\n})\n```\n\n`./build.js -run` will run your command as specified\nwhile simply `./build.js` won't cause the program to run.\n\n\n\n### Building multiple products at once\n\nestrella can build multiple variants of your program at once.\nExample `build.js` script:\n\n```js\n#!/usr/bin/env node\nconst { build } = require(\"estrella\")\nconst common = {\n  entry: \"src/main.ts\",\n  bundle: true,\n}\nbuild({\n  ...common,\n  outfile: \"out/foo.min.js\",\n})\nbuild({\n  ...common,\n  outfile: \"out/foo.debug.js\",\n  sourcemap: true,\n  debug: true,\n})\n```\n\nThen run the script to build both an optimized product and a debug product:\n\n```txt\n$ ./build.js\nWrote out/foo.min.js (445 bytes, 6.67ms)\nWrote out/foo.debug.{js,js.map} (2.4kb, 10.59ms)\nTS: OK\n```\n\nTypeScript diagnostics are run for all unique tsconfig.json files\n(or project directory in the absence of a tsconfig.json file), so in this case we get just\none report, as is expected.\n\nIn fact, since estrella is just a simple library, you can really do whatever you want\nin your build script.\n\n\n\n### Pre-processing and post-processing\n\nSetting `onStart` and/or `onEnd` in a build config allows you to hook into the esbuild cycle.\n`onStart(config, changedFiles)` is called when a build starts and `onEnd(config, result)`\nwhen a build finishes.\nThis works in both `-watch` mode and regular \"one shot\" mode.\n\nThese callbacks can optionally be async (i.e. return a Promise) which estrella will await.\nThis gives you the ability to perform detailed pre-processing and post-processing,\nlike requesting some stuff from the internet.\n\nExample build script using `onEnd` to show desktop notifications with\n[node-notifier](https://github.com/mikaelbr/node-notifier) in watch mode:\n\n```js\n#!/usr/bin/env node\nconst { build } = require(\"estrella\")\nconst notifier = require(\"node-notifier\")\nbuild({\n  entry: \"src/main.ts\",\n  outfile: \"out/foo.js\",\n  onEnd(config, result) {\n    config.watch \u0026\u0026 notifier.notify({\n      title: config.title,\n      message: result.errors.length \u003e 0 ?\n        `Build failed with ${result.errors.length} errors` :\n        `Build succeeded`\n    })\n  },\n})\n```\n\n\n\n### Watching arbitrary files for changes\n\nestrella comes with functions for scanning and watching any files or directories for changes,\nmaking it easy to work with other source files not handled by esbuild.\nLike for example CSS or code generation.\n\nExample build script:\n\n```js\n#!/usr/bin/env node\nconst { build, scandir, watch, cliopts } = require(\"estrella\")\n\nbuild({\n  entry: \"src/main.ts\",\n  outfile: \"out/foo.js\",\n})\n\nfunction generateCode(file) {\n  console.log(`generate ${file} -\u003e ${file}.js`)\n  // replace with actual logic\n}\n\n// generate all files initially\nconst dir = \"src\", filter = /\\..*$/i\nscandir(dir, filter, {recursive:true}).then(files =\u003e {\n  files.map(generateCode)\n  // in watch mode, generate files as they change\n  cliopts.watch \u0026\u0026 watch(dir, {filter, recursive:true}, changes =\u003e {\n    changes.map(c =\u003e generateCode(c.name))\n  })\n})\n```\n\n\n### Running a livereload web server\n\nSay you are building a website. You may want to run a HTTP server while in watch mode\nwhich automatically reloads your website as you develop it.\nSimply run a web server like [serve-http](https://www.npmjs.com/package/serve-http)\nin your build script:\n\n```js\n#!/usr/bin/env node\nconst { build, cliopts } = require(\"estrella\")\nbuild({\n  entry: \"src/main.ts\",\n  outfile: \"docs/app.js\",\n})\n// Run a local web server with livereload when -watch is set\ncliopts.watch \u0026\u0026 require(\"serve-http\").createServer({\n  port: 8181,\n  pubdir: require(\"path\").join(__dirname, \"docs\"),\n})\n```\n\nNow when you run your build script in watch mode a web server is run as well:\n\n```txt\n$ ./build.js -w\nserving ./ at http://localhost:8181/\nWrote docs/app.js (914 bytes, 12.44ms)\nTS: OK\n```\n\n\n### estrella as a program\n\nestrella can also be used directly as a program:\n\n```txt\n$ estrella src/foo.ts -o foo.js\nWrote foo.js (222 bytes, 7.91ms)\nTS: OK\n```\n\n```txt\n$ estrella -h\nusage: estrella [options] \u003csrcfile\u003e ...\noptions:\n  -w, -watch           Watch source files for changes and rebuild.\n  -g, -debug           Do not optimize and define DEBUG=true.\n  -r, -run             Run the output file after a successful build.\n  -sourcemap           Generate sourcemap.\n  -inline-sourcemap    Generate inline sourcemap.\n  -no-color            Disable use of colors.\n  -no-clear            Disable clearing of the screen, regardless of TTY status.\n  -no-diag             Disable TypeScript diagnostics.\n  -color               Color terminal output, regardless of TTY status.\n  -diag                Only run TypeScript diagnostics (no esbuild.)\n  -quiet               Only log warnings and errors but nothing else.\n  -silent              Don't log anything, not even errors.\n  -estrella-version    Print version of estrella and exit 0.\n  -estrella-debug      Enable debug logging of estrella itself.\n  -o=,-outfile=\u003cfile\u003e  Write output to \u003cfile\u003e instead of stdout.\n  -bundle              Include all dependencies.\n  -minify              Simplify and compress generated code.\n  -outdir=\u003cdir\u003e        Write output to \u003cdir\u003e instead of stdout.\n  -esbuild=\u003cjson\u003e      Pass arbitrary JSON to esbuild's build function.\n\n\u003csrcfile\u003e is a filename, or \"-\" for stdin.\n```\n\nSee `estrella -h` for more details.\n\n\n### Developing for Estrella\n\nLike any respectable compiler, Estrella of course builds itself.\n\nSetup instructions:\n\n```\ngit clone https://github.com/rsms/estrella.git\ncd estrella\nnpm install\n```\n\nBuild instructions:\n\n- Build debug products: `./build.js -g` (add `-w` for incremental compilation)\n- Build release products: `./build.js` (add `-w` for incremental compilation)\n- Build release products and run all tests: `./test/test.sh` (or `npm test`)\n- Build debug products and run all tests: `./test/test.sh -debug`\n\n\n\n### Contributing to Estrella\n\nContributions are very welcome!\nWhen contributing, please follow these guidelines:\n\n- Use welcoming and inclusive language\n- Be respectful of differing viewpoints and experiences\n- Gracefully accept constructive criticism\n- Focus on what is best for the community\n- Show empathy towards other community members\n\nTypes of contributions and how best to make them:\n\n- **Proposal for a new feature:**\n  [Open an issue and start a conversion.](https://github.com/rsms/estrella/issues)\n  Please do not create a PR until we've had time to discuss how to best approach the change.\n\n- **Fix for a bug:**\n  [Please open a PR with your fix](https://github.com/rsms/estrella/pulls)\n  and if you can, include a test that fails without your change but passes with it.\n\n- **Minor changes like spelling mistakes:**\n  [Open an issue](https://github.com/rsms/estrella/issues) and point out the concern.\n  Please do not create a PR for small things like spelling mistakes.\n\nThank you for being a great person \u0026 contributor!\n","funding_links":[],"categories":["TypeScript","typescript","JavaScript Ecosystem"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsms%2Festrella","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frsms%2Festrella","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsms%2Festrella/lists"}