{"id":17463596,"url":"https://github.com/rosszurowski/tandem","last_synced_at":"2025-04-19T18:25:40.369Z","repository":{"id":65298911,"uuid":"584203846","full_name":"rosszurowski/tandem","owner":"rosszurowski","description":"Parallel task runner for servers and long-running commands.","archived":false,"fork":false,"pushed_at":"2023-02-03T10:50:04.000Z","size":844,"stargazers_count":65,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-12-25T16:40:28.692Z","etag":null,"topics":["concurrently","golang","make","parallel","watch"],"latest_commit_sha":null,"homepage":"","language":"Go","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/rosszurowski.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-01-01T20:20:44.000Z","updated_at":"2024-11-14T07:13:36.000Z","dependencies_parsed_at":"2023-01-16T09:46:18.270Z","dependency_job_id":"bad16288-1951-43a2-926d-604cdcbeae97","html_url":"https://github.com/rosszurowski/tandem","commit_stats":{"total_commits":19,"total_committers":1,"mean_commits":19.0,"dds":0.0,"last_synced_commit":"2c49a4a79023dd936030afbc6bc95b52033c8981"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosszurowski%2Ftandem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosszurowski%2Ftandem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosszurowski%2Ftandem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosszurowski%2Ftandem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rosszurowski","download_url":"https://codeload.github.com/rosszurowski/tandem/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231544357,"owners_count":18392999,"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":["concurrently","golang","make","parallel","watch"],"created_at":"2024-10-18T10:24:33.915Z","updated_at":"2024-12-27T21:42:39.019Z","avatar_url":"https://github.com/rosszurowski.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\".github/cover.svg\" width=\"400\" alt=\"tandem — a fast and small parallel task runner (logo by Hannah Lee)\" /\u003e\n\u003c/div\u003e\n\n\u003cbr /\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cb\u003etandem\u003c/b\u003e is a task runner for parallel dev servers.\u003cbr /\u003eSmall, fast, and pairs great with Makefiles!\u003cbr\u003e\n\u003c/div\u003e\n\n## Features\n\n- Small, fast, static binary.\n- Shuts down each command if one fails. No more processes clinging to ports.\n- Supports running npm scripts and binaries.\n- Labels output for each command.\n\n## Demo\n\n![A screencast demo of using the tandem CLI.](.github/demo.gif)\n\n## Installation\n\nOn macOS, you can install with:\n\n```shell\nbrew install rosszurowski/tap/tandem\n```\n\nIf you have Go installed, you can install from the source with:\n\n```shell\ngo install github.com/rosszurowski/tandem@latest\n```\n\nIf you're using tandem from a Makefile, [this snippet](#using-in-makefiles) shows how to download a locally cached copy.\n\n## Usage\n\nUse tandem by passing a set of commands to run in parallel. Wrap each command in quotes, like so:\n\n```shell\ntandem 'command1 \"arg\"' 'command2 \"arg\"' 'command3 \"arg\"'\n```\n\n### Running a front-end and a backend at once\n\nWorking on a Next.js app, you might want to run your front-end dev server alongside a backend API server with live updating changes through [nodemon](https://nodemon.io/):\n\n```shell\n$ tandem 'next dev' 'nodemon --quiet ./server.js'\nnext     ready - started server on 0.0.0.0:3000, url: http://localhost:3000\nnext     event - compiled client and server successfully in 15 ms (25 modules)\nnodemon  starting server...\nnodemon  listening on http://localhost:3001\n```\n\n### Running npm scripts\n\nIf your scripts are defined in `package.json`, you can reference them by using `npm:` as a prefix:\n\n```json\n{\n  \"scripts\": {\n    \"dev:php\": \"...\",\n    \"dev:js\": \"...\",\n    \"dev:css\": \"...\"\n  }\n}\n```\n\n```shell\n$ tandem 'npm:dev:php' 'npm:dev:js' 'npm:dev:css'\n```\n\nWildcard rules like `npm:dev:*` are also supported as a shortcut. This line is equivalent to the above:\n\n```shell\n$ tandem 'npm:dev:*'\n```\n\n### Using in Makefiles\n\nIn a Makefile, use this snippet to fetch a local copy for your project. Change the `.cache` path as needed, and add it to your `.gitignore`.\n\n```makefile\ndev: node_modules .cache/tandem\n\t@.cache/tandem 'command1' 'command2'\n.PHONY: dev\n\n.cache/tandem:\n\t@mkdir -p $$(dirname $@)\n\t@curl -fsSL https://raw.githubusercontent.com/rosszurowski/tandem/main/install.sh | bash -s -- --dest=\"$$(dirname $@)\"\n```\n\nRunning `make dev` will download tandem once, and then use it for every run from there on out.\n\n## Motivation\n\nI regularly use Makefiles to automate project commands and tools. Makefiles are mostly great! But their biggest failing (also a failing of shells generally) is that it's shockingly hard to coordinate multiple commands as one group:\n\n- `make -jN \u003ca\u003e \u003cb\u003e \u003cc\u003e` doesn't end all tasks when another one fails. For running local dev servers, this means you can lose your CSS or JS watcher and not realize.\n- `command1 \u0026 command2 \u0026 wait` often leaves commands hanging around in the background, which is annoying when it eats up a port you want to use.\n- Tools like GNU parallel have a confusing syntax, and I've never been able to figure out how to stop all tasks when one fails.\n\ntandem makes running concurrent servers easy. It takes inspiration from [concurrently](https://www.npmjs.com/package/concurrently) or [npm-run-all](https://www.npmjs.com/package/npm-run-all), but improves performance and works as a static binary.\n\n## Acknowledgements\n\ntandem owes a big thanks to [hivemind](https://github.com/DarthSim/hivemind), from which much of the source is drawn. `tandem` can be thought of as a fork of hivemind, but rather than defining commands in a Procfile, defining them from a list of arguments.\n\ntandem's illustration was drawn by [Hannah Lee](https://hannahlee.ca/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosszurowski%2Ftandem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frosszurowski%2Ftandem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosszurowski%2Ftandem/lists"}