{"id":20970586,"url":"https://github.com/mitmadness/chuck","last_synced_at":"2025-05-14T11:33:37.636Z","repository":{"id":20150415,"uuid":"89381504","full_name":"mitmadness/chuck","owner":"mitmadness","description":":arrows_counterclockwise: :package: chuck is a webservice that makes Unity3D AssetBundles from various asset types","archived":false,"fork":false,"pushed_at":"2023-08-17T08:17:49.000Z","size":571,"stargazers_count":26,"open_issues_count":11,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-24T03:38:37.868Z","etag":null,"topics":["assetbundle","build-automation","unity3d","webservice"],"latest_commit_sha":null,"homepage":"","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/mitmadness.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":"2017-04-25T16:13:47.000Z","updated_at":"2025-02-15T01:33:05.000Z","dependencies_parsed_at":"2023-01-11T20:44:16.659Z","dependency_job_id":null,"html_url":"https://github.com/mitmadness/chuck","commit_stats":{"total_commits":172,"total_committers":5,"mean_commits":34.4,"dds":0.2790697674418605,"last_synced_commit":"b9a201f5b2382c94d2507dc0b15143feecc71f2c"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitmadness%2Fchuck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitmadness%2Fchuck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitmadness%2Fchuck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitmadness%2Fchuck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitmadness","download_url":"https://codeload.github.com/mitmadness/chuck/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254131852,"owners_count":22020028,"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":["assetbundle","build-automation","unity3d","webservice"],"created_at":"2024-11-19T03:59:43.444Z","updated_at":"2025-05-14T11:33:37.140Z","avatar_url":"https://github.com/mitmadness.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://github.com/mitmadness/chuck/raw/master/chuck.png\" alt=\"chuck webservice logo\" align=\"right\"\u003e\n\n# chuck [![npm version](https://img.shields.io/npm/v/@mitm/chuck.svg?style=flat-square)](https://www.npmjs.com/package/@mitm/chuck) ![license](https://img.shields.io/github/license/mitmadness/chuck.svg?style=flat-square) [![Travis Build](https://img.shields.io/travis/mitmadness/chuck.svg?style=flat-square)](https://travis-ci.org/mitmadness/chuck)\n\nchuck is a webservice that converts files that Unity understands to Unity3D AssetBundles.\n\nFrom the Unity3D [documentation](https://docs.unity3d.com/Manual/AssetBundlesIntro.html):\n\n\u003e AssetBundles are files which you can export from Unity to contain Assets of your choice, [that] can be loaded on demand by your application. This allows you to stream content, such as models, Textures, audio clips, or even entire Scenes [...].\n\nChuck notably features REST \u0026 Server-Sent APIs, a command-line interface, an admin page for managing API keys, and integrates [Toureiro](https://github.com/Epharmix/Toureiro) for viewing queued jobs.\n\n*:point_right: See also: [@mitm/assetbundlecompiler](https://github.com/mitmadness/AssetBundleCompiler), fluent JavaScript API to create AssetBundles from any files.*\n\n*:point_right: See also: [@mitm/unityinvoker](https://github.com/mitmadness/UnityInvoker), invoke Unity3D CLI with a fluent JavaScript API.*\n\n----------------\n\n - [Requirements](#requirements)\n - [Installation](#installation): [Standalone](#standalone-installation) / [Embedded](#embedded-installation) \n - [Configuration](#configuration)\n - [Public REST API](#public-rest--sse-api)\n - Extra tools: [Command Line Interface](#command-line-interface) / [Admin Web Interface](#admin-web-interface) / [Toureiro](#toureiro)\n - [Development \u0026 Contributing](#development--contributing)\n\n----------------\n\n## Requirements\n\n - **[Node.js](https://nodejs.org/en/)** v.7 or higher ;\n - **[yarn](https://yarnpkg.com/en/)** dependency manager, for development or standalone installation ;\n - An Azure account where chuck will send its generated asset bundles (limitation) ;\n - A running **[MongoDB](https://www.mongodb.com/)** server ;\n - A running **[Redis](https://redis.io/)** server ;\n - :warning: **An _activated_ installation of Unity on the machine** :warning:\n   - If Unity is not installed in the standard path, configure the path via the [Configuration](#configuration)\n   - You must activate Unity if not already done, even with a free plan, read [Unity activation](https://github.com/mitmadness/AssetBundleCompiler#unity-activation) from AssetBundleCompiler\n\nAlso, except logging them, chuck can optionally report fatal errors on [Sentry](https://sentry.io/welcome/). To enable this, [configure](#configuration) your Sentry DSN.\n\n## Installation\n\nPlease note that chuck is not a pure library, nor a reusable Express middleware. It's a standalone application with its own logging, database, etc. But it can also be installed as an npm package for writing plugins or configuring and boot it.\n\n### Standalone installation \n\n\u003cdetails\u003e\n\u003csummary\u003eClassical approach. Use this to deploy chuck directly without integrating it to another application (except API communication of course)\u003c/summary\u003e\n\n#### 1. Install the application and dependencies\n\n```\n$ git clone git@github.com:mitmadness/chuck.git \u0026\u0026 cd chuck\n$ yarn install\n$ yarn build\n```\n\n#### 2. Configure Chuck\n\nCreate a blank `.env` file at the root.\n\nLook at the `.env.defaults` file (don't delete it, it's part of the application), it contains key/value pairs of environment variables.\n\nYou can now override values from `.env.defaults` to match your own environment when the default values are incorrect.\n\nYou can also, of course, set environment variables by hand with your preferred method (exports, inline variables when launching the command...).\n\n*:point_right: Read more about how configuration is mapped with environment variables in [Using environment variables](#using-environment-variables)*\n\n#### 3. Run it\n\nRun `yarn start`. That's it.\n\nTo use chuck plugins, install them (ex. `yarn add @mitm/chuck-ifc`) then ask chuck to load them via the `CHUCK_STEPMODULEPLUGINS` environment variable:\n\n```\nCHUCK_STEPMODULEPLUGINS=@mitm/chuck-ifc,myplugin yarn start\n```\n\u003c/details\u003e\n\n### Embedded installation \n\n\u003cdetails\u003e\n\u003csummary\u003eChuck app integration into another package: chuck as a npm package. This is the preferred method and it gives you more flexibility, doesn't need compilation, permits better versioning, etc.\u003c/summary\u003e\n\n#### 1. Install chuck via its package\n\n```\nyarn add @mitm/chuck\n```\n\n#### 2. Configure \u0026 boot it\n\nYou can either set up your own entry point and configure it in JavaScript (see [Configuration](#configuration)), or you can still use environment variables.\n\n**With environment variables**, do it like this:\n\n```\nCHUCK_SERVERPORT=80 CHUCK_MONGOURL=mongodb://localhost/chuck yarn chuck\n```\n\nYou can also, of course, set environment variables by hand with your preferred method (exports, inline variables when launching the command...).\n\nRun the CLI similarly with `yarn chuck-cli`.\n\n*:point_right: Read more about how configuration is mapped with environment variables in [Using environment variables](#using-environment-variables)*\n\n**With your own entry point**:\n\nCreate a file named, for example, `chuck.ts` in your project:\n\n```typescript\nimport { boot } from '@mitm/chuck';\n\nboot({\n    serverPort: 80,\n    mongoUrl: 'mongodb://localhost/chuck'\n});\n```\n\nYou can still use environment variables with `boot()`.\n\u003c/details\u003e\n\n## Configuration\n\n### Available configuration keys\n\n\u003cdetails\u003e\n\u003csummary\u003eThis is the interface for the available configuration\u003c/summary\u003e\n\n```ts\ninterface IChuckConfig {\n    // aka NODE_ENV. Configures the mode (`development` or `production`) in which the server is running.\n    // development: permissive CORS rules are set on the API\n    // production: timestamps in log messages and more verbose HTTP logs\n    // Defaults to process.env.NODE_ENV or, if undefined, \"development\"\n    env: EnvType;\n    \n    // Minimum log level (npm log levels, see https://github.com/winstonjs/winston#logging-levels).\n    // Defaults to \"verbose\"\n    logLevel: string;\n    \n    // Server HTTP port.\n    // Defaults to 3001\n    serverPort: number;\n    \n    // Connection string to a MongoDB database.\n    // Defaults to mongodb://localhost/chuck\n    mongoUrl: string;\n    \n    // DSN for Sentry error reporting.\n    // Reporting is disabled if this is not set.\n    ravenDsn: string;\n    \n    // Redis connection informations.\n    // Defaults to { host: 'localhost', port: 6379, db: 0 }\n    redis: { host: string; port: number; db: number };\n    \n    // Admin Web UIs configuration. Used by the admin interface and Toureiro.\n    // Default to { enable: false, user: 'admin', password: 'admin' }\n    adminWebUis: { enable: boolean, user: string; password: string; };\n    \n    // Unity Editor path (if not installed in the standard path), see https://github.com/mitmadness/AssetBundleCompiler#changing-unitys-executable-path\n    // Default to undefined (auto)\n    unityPath: string;\n    \n    // Azure configuration.\n    // Default to { enableEmu: false }\n    azure: { enableEmu: boolean; };\n    \n    /**\n     * An array of module names.\n     * Those modules will be loaded dynamically as step plugins.\n     */\n    stepModulePlugins: string[];\n}\n```\n\u003c/details\u003e\n\n### Using environment variables\n\n\u003cdetails\u003e\n\u003csummary\u003eChuck is primarily configurable via environment variables. Read here how to map the configuration interface options on environment variables.\u003c/summary\u003e\n\nYou can set environement variables in the way you prefer. Tou can set them inline, in the CLI command that launches chuck, via a shell `export`, or for example, if you use the standalone installation, via an `.env` file at root that overrides Chuck's `.env.defaults` values (only for redefined keys).\n\nThen, environment variables are simply mapped to the real configuration. Take those example:\n\n - To set `config.logLevel`, set `CHUCK_LOGLEVEL`\n - To set `config.adminWebUis.enable`, set `CHUCK_ADMINWEBUIS_ENABLE`.\n \nEtc. Prefix with `CHUCK_` and replace dots with underscores, all uppercase.\n\u003c/details\u003e\n\n## Public REST / SSE API\n\nChuck exposes a simple REST and [SSE (Server-Sent Events)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) API for converting files to asset bundles.\n\n### Create a new conversion request\n\n`POST /api/conversions`\n\n\u003cdetails\u003e\n\u003csummary\u003eThis endpoint will create a conversion request. It will immediately push on the conversions queue, so the job will start as soon as possible (conversions are ran sequentially).\u003c/summary\u003e\n\n#### Request\n\n:closed_lock_with_key: This endpoint requires authentication using an API key. You can generate one either via the CLI, or via the web interface. Pass the API key like this: `Authorization: Bearer YOUR_API_KEY`.\n\nNote: `compilerOptions` is an object of options to pass to AssetBundleCompiler ([abcompiler's reference](https://github.com/mitmadness/AssetBundleCompiler#link-simple-fluent-api)).\n\nNote: `azure.sharedAccessSignatureToken` is an [Azure SAS token](https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1) that lets chuck create the asset bundle binary blob on Azure, without giving your Azure credentials to chuck. You can automate token creation with Azure CLI or Azure SDKs.\n\n```\nPOST /api/conversions\nContent-Type: application/json\nAuthorization: Bearer {{apiKey}}\n```\n```json\n{\n  \"assetBundleName\": \"myassetbundle.ab\",\n  \"compilerOptions\": {\n    \"targeting\": \"webgl\"\n  },\n  \"assetUrls\": [\n    \"https://url/to/a/file.fbx\",\n    \"https://url/to/another/file.ifc\"\n  ],\n  \"azure\": {\n    \"host\": \"{{azureHost}}\",\n    \"container\": \"{{azureContainer}}\",\n    \"sharedAccessSignatureToken\": \"{{azureSharedAccessSignatureToken}}\"\n  }\n}\n```\n\n#### Successful response\n\n```\nHTTP/1.1 202 Accepted\nContent-Type: application/json; charset=utf-8\n```\n```json\n{\n  \"assetBundleName\": \"myassetbundle.ab\",\n  \"conversion\": {\n    \"logs\": [],\n    \"assetBundleUrl\": null,\n    \"error\": null,\n    \"step\": null,\n    \"isCompleted\": false,\n    \"jobId\": \"138\"\n  },\n  \"compilerOptions\": {\n    \"targeting\": \"webgl\",\n    \"editorScripts\": [],\n    \"buildOptions\": {}\n  },\n  \"azure\": {\n    \"host\": \"{{azureHost}}\",\n    \"container\": \"{{azureContainer}}\",\n    \"sharedAccessSignatureToken\": \"{{azureSharedAccessSignatureToken}}\"\n  },\n  \"assetUrls\": [\n    \"https://url/to/a/file.fbx\",\n    \"https://url/to/another/file.ifc\"\n  ],\n  \"code\": \"00cad557-5acc-4c6b-a987-79f650d67197\"\n}\n```\n\u003c/details\u003e\n\n### Retrieve a conversion request\n\n`GET /api/conversions/{{code}}`\n\n\u003cdetails\u003e\n\u003csummary\u003eRetrieves a previously-posted conversion request. This endpoint has no authentication as the conversion code adds a first layer of security (moreover, conversion requests are not editable).\u003c/summary\u003e\n\n#### Request\n\n```\nGET /api/conversions/{{conversionCode}}\n```\n\n#### Successful response (completed conversion)\n\n```\nHTTP/1.1 200 OK\nContent-Type: application/json; charset=utf-8\n```\n```json\n{\n  \"assetBundleName\": \"myassetbundle.ab\",\n  \"conversion\": {\n    \"assetBundleUrl\": \"https://{{azureHost}}/{{azureContainer}}/myassetbundle.ab\",\n    \"error\": null,\n    \"step\": null,\n    \"isCompleted\": true,\n    \"jobId\": \"139\"\n  },\n  \"compilerOptions\": {\n    \"targeting\": \"webgl\",\n    \"editorScripts\": [],\n    \"buildOptions\": {}\n  },\n  \"azure\": {\n    \"host\": \"{{azureHost}}\",\n    \"container\": \"{{azureContainer}}\",\n    \"sharedAccessSignatureToken\": \"{{azureSharedAccessSignatureToken}}\"\n  },\n  \"assetUrls\": [\n    \"https://url/to/a/file.fbx\",\n    \"https://url/to/another/file.ifc\"\n  ],\n  \"code\": \"00cad557-5acc-4c6b-a987-79f650d67197\"\n}\n```\n\n#### Successful response (failed conversion)\n\n```\nHTTP/1.1 200 OK\nContent-Type: application/json; charset=utf-8\n```\n```json\n{\n  ...\n  \"conversion\": {\n    \"assetBundleUrl\": null,\n    \"error\": {\n      \"name\": \"Error\",\n      \"message\": \"Error(s) while downloading assets\",\n      \"errors\": [\n        {\n          \"name\": \"FetchError\",\n          \"message\": \"request to https://url/to/a/file.fbx failed, reason: getaddrinfo ENOTFOUND url url:443\"\n        },\n        {\n          \"name\": \"FetchError\",\n          \"message\": \"request to https://url/to/another/file.ifc failed, reason: getaddrinfo ENOTFOUND url url:443\"\n        }\n      ]\n    },\n    \"step\": \"cleanup\",\n    \"isCompleted\": true,\n    \"jobId\": \"140\"\n  },\n  ...\n}\n```\n\u003c/details\u003e\n\n### Real-time conversion job's events\n\n`GET /api/conversions/{{code}}/events`\n\n\u003cdetails\u003e\n\u003csummary\u003eThis is the only way to know precisely when a conversion is completed (or failed). It also sends various events concerning the job state, which step is running, and various logging informations.\u003c/summary\u003e\n\n**This is an Server-Sent Events (SSE) endpoint**, use the browser's native interface `EventSource` to access it, or a browser/node.js polyfill like the [eventsource](https://www.npmjs.com/package/eventsource) package on npm.\n\n#### Request\n\n```\nGET /api/conversions/{{conversionCode}}/events\n```\n\nAvailable query parameters:\n\n - `?sseType={events|data}`: whether to use data-only SSE messages or event+data. If using `data`, the event name will be in the `type` property of the data-only message. Defaults to `events`.\n - `?replay={true|false}`: whether to dump missed events between the job start and the connection to the SSE endpoint. Defaults to `true`.\n\n#### Unsuccessful response\n\nTwo classic HTTP errors may occur before the SSE session starts (errors are formatted the same way there are on the rest of the API).\n\n - `404 Not Found` when the conversion code given in the URL is unknown ;\n - `410 Gone` when `?replay=false` and the conversion is already terminated (success or error).\n\nThe client can handle this using `EventSource.onerror`.\n\n#### Successful response (completed conversion)\n\n:bulb: Note: The server will close the connection as soon as the conversion is terminated, error or success. As the SSE spec does not allow a server to close the connection gracefully, the client MUST listen for errors, and call EventSource#close() itself to avoid automatic reconnection.\n\n```typescript\nev.onerror = (event) =\u003e {\n    if (event.eventPhase == EventSource.CLOSED) {\n        ev.close();\n    }\n};\n```\n\n:bulb: Note: The client will probably most interested in the `queue/conversion-ended` event that contains either an error or an URL to the resulting asset bundle.\n\n```\nHTTP/1.1 200 OK\nContent-Type:text/event-stream; charset=utf-8\nCache-Control: no-cache\n\n: sse-start\nevent: processor/step-change\ndata: {\"step\":{\"priority\":10,\"name\":\"Download remote assets\",\"code\":\"download-assets\"},\"message\":\"Starting \\\"Download remote assets\\\"\"}\n\nevent: queue/conversion-start\ndata: {\"message\":\"Conversion started\"}\n\nevent: processor/download-assets/start-download\ndata: {\"message\":\"Downloading \\\"https://i.ytimg.com/vi/qIIN64bUbsI/maxresdefault.jpg\\\"\"}\n\nevent: processor/step-change\ndata: {\"step\":{\"priority\":30,\"name\":\"Execute AssetBundleCompiler to assemble the asset bundle\",\"code\":\"exec-assetbundlecompiler\"},\"message\":\"Starting \\\"Execute AssetBundleCompiler to assemble the asset bundle\\\"\"}\n\nevent: processor/exec-assetbundlecompiler/abcompiler-log\ndata: {\"message\":\"Preparing Unity project in /tmp/AssetBundleCompiler\"}\n\nevent: processor/exec-assetbundlecompiler/abcompiler-log\ndata: {\"message\":\"Copying assets to /tmp/AssetBundleCompiler/Assets/CopiedAssets\"}\n\nevent: processor/exec-assetbundlecompiler/abcompiler-log\ndata: {\"message\":\"Copying custom editor scripts to /tmp/AssetBundleCompiler/Assets/Editor/CopiedScripts\"}\n\nevent: processor/exec-assetbundlecompiler/abcompiler-log\ndata: {\"message\":\"Generating asset bundle in /tmp/AssetBundleCompiler/GeneratedAssetBundles\"}\n\nevent: processor/exec-assetbundlecompiler/abcompiler-log\ndata: {\"message\":\"Updating resource: maxresdefault.jpg\"}\n\nevent: processor/exec-assetbundlecompiler/abcompiler-log\ndata: {\"message\":\"Moving asset bundle to target destination\"}\n\nevent: processor/exec-assetbundlecompiler/abcompiler-log\ndata: {\"message\":\"Cleaning up the Unity project\"}\n\nevent: processor/exec-assetbundlecompiler/abcompiler-log\ndata: {\"message\":\"Done.\"}\n\nevent: processor/step-change\ndata: {\"message\":\"Starting \\\"Upload the AssetBundle on Azure\\\"\",\"step\":{\"code\":\"upload-bundle\",\"name\":\"Upload the AssetBundle on Azure\",\"priority\":40}}\n\nevent: processor/upload-bundle/upload-start\ndata: {\"message\":\"Uploading \\\"/tmp/chuck-exec-assetbundlecompiler-1495536189347/myassetbundle.ab2\\\" to Azure\"}\n\nevent: processor/upload-bundle/upload-end\ndata: {\"message\":\"Upload terminated with success\",\"blobUrl\":\"https://mitmtest.blob.core.windows.net/assetbundles/myassetbundle.ab2\",\"blobResult\":{\"container\":\"assetbundles\",\"name\":\"myassetbundle.ab2\",\"lastModified\":\"Tue, 23 May 2017 10:43:19 GMT\",\"etag\":\"\\\"0x8D4A1C886E0CAC4\\\"\",\"requestId\":\"54ef0e35-0001-0088-4db1-d3adde000000\",\"contentSettings\":{\"contentMD5\":\"xRF+eIadlPTWCVp8Y8IkjA==\"}}}\n\nevent: processor/step-change\ndata: {\"message\":\"Performing cleanup for steps: download-assets, exec-assetbundlecompiler, upload-bundle (All steps have terminated successfuly)\",\"step\":{\"code\":\"cleanup\",\"name\":\"Conversion artifacts cleanup\",\"priority\":null}}\n\nevent: queue/conversion-ended\ndata: {\"message\":\"Conversion terminated with success!\",\"assetBundleUrl\":\"https://mitmtest.blob.core.windows.net/assetbundles/myassetbundle.ab2\",\"error\":null}\n\n: sse-keep-alive\n: sse-keep-alive\n```\n\u003c/details\u003e\n\n## Extras tools\n\n### Command Line Interface\n\nChuck provides a CLI tool that is exported as the `bin` file in the package. In standalone mode, use it with `yarn cli -- --arguments`.\n\nExamples (using chuck as a package):\n\n - **`yarn chuck-cli help`** get available commands\n - **`yarn chuck-cli help \u003ccommand\u003e`** displays informations about a command and available arguments\n - **`yarn chuck-cli api:generate-key`** generates an API key. Pass `--save` to save the generated key to the database.\n - **`yarn chuck-cli api:revoke-key \u003ckey\u003e`** revokes an API key stored in the database.\n\n### Admin Web Interface\n\nA very, very simple administration interface is available under https://chuck/admin and uses HTTP Basic authentication, with the same credentials as Toureiro (see [Configuration](#configuration) section).\n\nIt lets you create and revoke API keys as an alternative to the CLI.\n\n### Toureiro\n\nChuck embarks [Toureiro](https://github.com/Epharmix/Toureiro), which is...\n\n\u003e A graphical monitoring interface for the distributed job queue bull built using express and react. Toureiro provides simple monitoring features as well as the ability to promote delayed jobs directly.\n\nToureiro's interface can be found on https://chuck/toureiro, and is protected by the same HTTP Basic Auth and credentials used to login to the administration interface (see [Configuration](#configuration) section).\n\n![Toureiro Web Interface](https://raw.githubusercontent.com/Epharmix/Toureiro/screenshots/public/screenshots/Job%20List.png)\n\n## Development \u0026 Contributing\n\nThe workflow is based on npm scripts:\n\n  - `yarn watch`: starts the TypeScript compiler in watch mode ;\n  - `yarn build`: compile TypeScript sources ;\n  - `yarn start`: (run `watch` or `build` before!) starts the server and restarts it when the compiled files change (production or development, but for production you could use [pm2](http://pm2.keymetrics.io/) with `yarn standalone`) ;\n  - `yarn cli`: shortcut to chuck's CLI (usage: `yarn cli -- command --arg1 --arg2`) ;\n  - `yarn standalone`: starts the Express server without nodemon ;\n  - `yarn lint`: checks code style on the TypeScript sources (recommended: install typescript and tslint extensions for your editor).\n  \nSo, basically, to start a development session, run in a terminal:\n\n```\nyarn install\nyarn watch\n```\n\nIn a terminal aside of the first one, run:\n\n```\nyarn start\n```\n\nYou can also create an `.env` file at the project root to override the default environment variables in `.env.defaults`. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitmadness%2Fchuck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitmadness%2Fchuck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitmadness%2Fchuck/lists"}