{"id":15287655,"url":"https://github.com/jayu/nodemcu-app","last_synced_at":"2026-01-23T04:57:19.222Z","repository":{"id":118315381,"uuid":"312914639","full_name":"jayu/nodemcu-app","owner":"jayu","description":"A tool-chain for efficient NodeMCU (ESP8266, ESP32) apps development","archived":false,"fork":false,"pushed_at":"2022-03-23T16:08:01.000Z","size":571,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-13T02:19:33.390Z","etag":null,"topics":["esp32","esp8266","nodemcu","nodemcu-tool","nodemcu-uploader"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jayu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2020-11-14T22:39:15.000Z","updated_at":"2022-04-03T15:37:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"0eb182b8-0e2f-4e85-87de-bc4fc42617ab","html_url":"https://github.com/jayu/nodemcu-app","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/jayu/nodemcu-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jayu%2Fnodemcu-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jayu%2Fnodemcu-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jayu%2Fnodemcu-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jayu%2Fnodemcu-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jayu","download_url":"https://codeload.github.com/jayu/nodemcu-app/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jayu%2Fnodemcu-app/sbom","scorecard":{"id":509318,"data":{"date":"2025-08-11","repo":{"name":"github.com/jayu/nodemcu-app","commit":"e2d354acfd5318b3d98c03ff1b28b7fd4b8f704f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"51 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-px4h-xg32-q955","Warn: Project is vulnerable to: GHSA-3j8f-xvm3-ffx4","Warn: Project is vulnerable to: GHSA-4p35-cfcx-8653","Warn: Project is vulnerable to: GHSA-7f3x-x4pr-wqhj","Warn: Project is vulnerable to: GHSA-jpp7-7chh-cf67","Warn: Project is vulnerable to: GHSA-q6wq-5p59-983w","Warn: Project is vulnerable to: GHSA-j9fq-vwqv-2fm2","Warn: Project is vulnerable to: GHSA-pqw5-jmp5-px4v","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-wpg7-2c88-r8xv","Warn: Project is vulnerable to: GHSA-pq67-2wwv-3xjx","Warn: Project is vulnerable to: GHSA-8cj5-5rvv-wf4v","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-38fc-wpqx-33j7","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T00:07:42.299Z","repository_id":118315381,"created_at":"2025-08-20T00:07:42.299Z","updated_at":"2025-08-20T00:07:42.299Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28680623,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T04:33:33.518Z","status":"ssl_error","status_checked_at":"2026-01-23T04:33:30.433Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["esp32","esp8266","nodemcu","nodemcu-tool","nodemcu-uploader"],"created_at":"2024-09-30T15:33:47.427Z","updated_at":"2026-01-23T04:57:19.216Z","avatar_url":"https://github.com/jayu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch3 align=\"center\"\u003e\n  \u003ccode\u003enodemcu-app\u003c/code\u003e\n\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  A tool-chain for efficient NodeMCU (ESP8266, ESP32) apps development\n\u003c/p\u003e\n\n---\n\n\u003cimg alt=\"nodemcu-app version\" src=\"https://img.shields.io/npm/v/nodemcu-app\"\u003e \u003cimg alt=\"nodemcu-app license\" src=\"https://img.shields.io/npm/l/nodemcu-app\"\u003e \u003cimg alt=\"nodemcu-app PRs welcome\" src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square\"\u003e\n\n## About\n\nThis project is a CLI tool with bunch of commands that helps develop non-trivial NodeMCU applications. It makes it easy to reuse modules across different projects and automates the process of LFS (Lua File Store) compilation and upload for maximizing the amount of free the RAM available on ESP boards.\n\n[Jump to CLI reference](#CLI-reference)\n\n### Features\n\n- 🖥️ Fully-featured **terminal** with output coloring and command history\n- ✨ Application scaffolding generation that creates a settings file to glue everything up\n- 🧩 Robust **module system** that allows to create custom reusable utilities\n- 📦 **Bundler** that is able to merge many source files into one\n- 🚢 **Uploader** that integrates already existing `nodemcu-uploader` or `nodemcu-tool` to bring all-in-one command for deploying your projects to the ESP\n- ✈️ Possibility to update LFS image Over The Air from CLI\n- 🖴 Ability to compile and upload **Lua byte code** or **LFS** image to save precious RAM. It's utilizing Lua cross compiler.\n- 🇾 Multi environment support to have different settings per device or firmware build including the power of env variables.\n\n#### Coming soon\n\n- 📥 Installing Lua packages from Luarocks or NodeMCU Github repo\n- 🕶️ watch mode for upload script to focus exclusively on coding\n- 🎯 Support for Lua script native module resolution algorithm\n- ☁️ Support for LFS compilation in the cloud to eliminated dependency on local compiler\n\n### TypeScript for micro controllers\n\nThe ultimate goal of this project is to bring an ability to write NodeMCU applications with TypeScript by utilizing awesome [https://typescripttolua.github.io/docs/getting-started/](TypeScriptToLua) compiler. However this is still at a conceptual phase.\n\n[Read about motivation and origin of the project](Motivation-and-origin-of-the-project)\n\n## Getting started\n\n### Installation\n\n\u003e If you are not familiar with JS environment, install [Node.js](https://nodejs.org) first\n\n```\nyarn global add nodemcu-app\n```\n\nor\n\n```\nnpm -i -g nodemcu-app\n```\n\n### Prerequisites\n\nThe CLI can be used standalone, however to leverage it's all potential you will have to equip with additional tools.\n\nTo use `upload` script you will have to install [`nodemcu-uploader`](https://github.com/kmpm/nodemcu-uploader) or [`nodemcu-tool`](https://github.com/AndiDittrich/NodeMCU-Tool). The former is much faster.\n\nTo use **compilation** feature, you will need Lua cross compiler (`luac.cross`). You can read in NodeMCU docs on how to [build one](https://nodemcu.readthedocs.io/en/release/getting-started/#build-luaccross) for yourself. `nodemcu-app init` will ask for the path to `luac.cross`.\n\nTo use **LFS upload** feature you will have to, except having `luac.corss`, build NodeMCU firmware with a special settings for LFS support. You can build it using [NodeMCU custom builds](https://nodemcu-build.com/) or other methods. Once you flash LFS-ready firmware to ESP8266, just use `--lfs` flag for `upload` script, and the CLI will take care of everything! For more details about LFS [documentation](https://nodemcu.readthedocs.io/en/release/getting-started/#compile-lua-into-lfs-image) is a good reading. If you really need to know more, read this [whitepaper](https://nodemcu.readthedocs.io/en/release/lfs/) in docs.\n\n### Creating `nodemcu-app` project\n\nTo start playing with other features than `terminal`, you will have to generate a project structure with a settings file.\n\nTo do so, run `nodemcu-app init` and you will be asked for several details. You can choose from two types of setup: `single` and `multiple`. Usually more useful is `multiple` setup with which you can re-use the same code across different projects. You might prefer to just have separate directory for each project, the `single` is for you.\n\n\u003e Prepare a path to `luac.cross` file in advance, if you plan to use [compilation or LFS](#Prerequisites)\n\nThe generates project structure looks like this:\n\n```\nmy-nodemcu-project\n├── luarocks_modules\n├── modules\n│   └── exampleModule.lua\n├── projects\n│   └── example-project\n│       └── init.lua\n└── settings.json\n```\n\nWhere `settings.json` is a file that stores information about generated project. Editing this file is on you risk!\n\n```json\n{\n  \"setupType\": \"multiple\",\n  \"manifestVersion\": \"1.1\",\n  \"default\": {\n    \"entryDir\": \"./projects\",\n    \"moduleDirs\": [\"./modules\", \"./luarocks_modules\"],\n    \"crossCompilerPath\": \"\",\n    \"uploadToolBinary\": \"nodemcu-uploader\"\n  }\n}\n```\n\n\u003e In this example we decided to not use cross compilation feature. However you can update the path to cross compiler when you get ready.\n\n### Using different environments\n\nAfter creating a project using `nodemcu-app init`, you can add as many environments as you like, next to the `default` environment.\n\nFor example, you might need to use different `luac.cross` for different firmware versions. In order to do this, you can add another environment to settings file, eg. `beta-firmware`:\n\n\u003e Note that `luac.cross` might not work properly between different firmware versions, eg 2.0 and 3.0\n\n```json\n{\n  \"setupType\": \"multiple\",\n  \"manifestVersion\": \"1.1\",\n  \"default\": {\n    \"entryDir\": \"./projects\",\n    \"moduleDirs\": [\"./modules\", \"./luarocks_modules\"],\n    \"crossCompilerPath\": \"./luac.cross\",\n    \"uploadToolBinary\": \"nodemcu-uploader\"\n  },\n  \"beta-firmware\": {\n    \"crossCompilerPath\": \"./beta-luac.cross\"\n  }\n}\n```\n\nIn order to use beta-firmware env, pass an `--env \u003cvalue...\u003e` flag to either `bundle` or `upload` script, eg.\n\n```sh\nnodemcu-app upload my-project --lfs --env beta-firmware\n```\n\n#### Environment variables\n\nYou can also specify env variables using `envVars` key in a given env setting, eg:\n\n```json\n{\n  \"setupType\": \"multiple\",\n  \"manifestVersion\": \"1.1\",\n  \"default\": {\n    \"entryDir\": \"./projects\",\n    \"moduleDirs\": [\"./modules\", \"./luarocks_modules\"],\n    \"crossCompilerPath\": \"./luac.cross\",\n    \"uploadToolBinary\": \"nodemcu-uploader\",\n    \"envVars\": {\n      \"IS_DEV\": \"true\"\n    }\n  },\n  \"beta-firmware\": {\n    \"crossCompilerPath\": \"./beta-luac.cross\"\n  },\n  \"prod\": {\n    \"envVars\": {\n      \"IS_DEV\": \"false\"\n    }\n  }\n}\n```\n\nYou can refer to given env var in the code using `$` sign followed by the variable name inside a string.\n\n\u003e Note that using env vars is currently only supported inside strings.\n\neg:\n\n```lua\nlocal isDev = \"$IS_DEV\"\nif (isDev) then\n  startWithDelay()\nelse\n  startWithoutDelay()\nend\n```\n\nEnv vars are interpolated during code bundling. You can not only use environment variables defined in `settings.json`, but also all variables defined in your OS will be available, eg:\n\n```sh\nSOME_VAR=VALUE nodemcu-app bundle/upload some-project\n```\n\nAll variables from selected environments will be merge into one set, starting from your OS env vars and ending on the last provided environment.\n\n#### Using multiple environments at the same time\n\nYou can use multiple environments at the same time. The environments will be merged into one, and the last you specified will eventually override values provided by the previous.\n\nFor given config file\n\n```json\n{\n  \"setupType\": \"multiple\",\n  \"manifestVersion\": \"1.1\",\n  \"default\": {\n    \"entryDir\": \"./projects\",\n    \"moduleDirs\": [\"./modules\", \"./luarocks_modules\"],\n    \"crossCompilerPath\": \"./luac.cross\",\n    \"uploadToolBinary\": \"nodemcu-uploader\",\n    \"envVars\": {\n      \"IS_DEV\": \"true\",\n      \"SERVER_ADDR\": \"localhost:3000\"\n    }\n  },\n  \"esp32\": {\n    \"crossCompilerPath\": \"./esp32-luac.cross\",\n    \"uploadToolBinary\": \"nodemcu-tool\"\n  },\n  \"remote-server\": {\n    \"envVars\": {\n      \"SERVER_ADDR\": \"example.com\"\n    }\n  },\n  \"prod\": {\n    \"envVars\": {\n      \"IS_DEV\": \"false\"\n    }\n  }\n}\n```\n\nand specifying environments like `--env esp32 remote-server prod`\n\nYou will end up with the following settings:\n\n```json\n{\n  \"entryDir\": \"./projects\",\n  \"moduleDirs\": [\"./modules\", \"./luarocks_modules\"],\n  \"crossCompilerPath\": \"./esp32-luac.cross\",\n  \"uploadToolBinary\": \"nodemcu-tool\",\n  \"envVars\": {\n    \"IS_DEV\": \"false\",\n    \"SERVER_ADDR\": \"example.com\"\n  }\n}\n```\n\n## CLI reference\n\n\u003c!-- cli-docs-start --\u003e\n\n### Command `terminal`\n\nRun fully-featured terminal with output coloring and command history. Can be used standalone, do not require nodemcu-app project.\n\n#### Usage\n\n```sh\nnodemcu-app terminal [options]\n```\n\n#### Options\n\n- `-c, --cmd \u003cstring\u003e` - Command to execute after starting the terminal (_optional_)\n- `-t, --timeout \u003cnumber\u003e` - Timeout after terminal should be closed in seconds (_optional_)\n- `-p, --port \u003cvalue\u003e` - serialport path eg. /dev/ttyUSB0 (_optional_)\n- `-br, --baudRate \u003cvalue\u003e` - connection baud rate (_optional_)\n\n### Command `init`\n\nRun interactive wizard that will create nodemcu-app project structure.\n\n#### Usage\n\n```sh\nnodemcu-app init\n```\n\n### Command `bundle`\n\nBundle a project and it's dependencies into one destination file\n\n#### Usage\n\n```sh\nnodemcu-app bundle [project-name] [options]\n```\n\n#### Arguments\n\n- `project-name` - Name of a project from entry directory (required for setup type multiple) (_optional_)\n\n#### Options\n\n- `-d, --dest [value]` - destination file path; defaults to 'dist/bundle.lua' (_optional_)\n- `-e, --env \u003cvalues...\u003e` - settings environment. \"default\" environment is always used. All selected environments are merged. Last provided environment is the most relevant. (_optional_)\n\n### Command `upload`\n\nCompile and upload a project to NodeMCU device using selected uploader\n\n#### Usage\n\n```sh\nnodemcu-app upload [project-name] [options]\n```\n\n#### Arguments\n\n- `project-name` - Name of a project from entry directory (required for setup type multiple) (_optional_)\n\n#### Options\n\n- `--noCompile` - Skip compilation process and upload raw .lua project bundle to NodeMCU. (_optional_)\n- `--lfs` - Indicates if Lua File Store should be used. Note that your device has to be flashed with special firmware build to support LFS. (_optional_)\n- `--lfsOta [url]` - Uploads LFS image to given url, typically an HTTP://{IP}:{PORT}, using POST request. Useful for update of LFS image after initial upload. Device has to run server that is capable of receiving binary file and reloading LFS image afterwards. Default url can be set in settings file as \"otaUrl\" (_optional_)\n- `-p, --port \u003cvalue\u003e` - serialport path eg. /dev/ttyUSB0 (_optional_)\n- `-br, --baudRate \u003cvalue\u003e` - connection baud rate (_optional_)\n- `-e, --env \u003cvalues...\u003e` - settings environment. \"default\" environment is always used. All selected environments are merged. Last provided environment is the most relevant. (_optional_)\n\n### Command `docs`\n\nGenerate documentation of available commands into md file.\n\n#### Usage\n\n```sh\nnodemcu-app docs \u003coutputPath\u003e [options]\n```\n\n#### Arguments\n\n- `outputPath` - path to output \\*.md file (**required**)\n\n#### Options\n\n- `-hl, --headerLevel \u003cvalue\u003e` - Initial header level (_optional_)\n\u003c!-- cli-docs-end --\u003e\n\n## Contributing\n\nProject is open to contributions, just rise an issue if you see any area for enhancement or you noticed a bug.\n\n## Development\n\nClone repo and install dependencies using `yarn`\n\nTo start development simply run build script in watch mode:\n\n`yarn build:watch`\n\nThe environment is ready, now run following command to start the cli:\n\n`yarn dev`\n\nDon't forget to run tests\n\n`yarn test:watch`\n\n## Motivation and origin of the project\n\nI come from JavaScript/TypeScript environment which is rich of ergonomic tooling that makes development really pleasant experience. This project is an attempt to bring some more ergonomics to NodeMCU ecosystem.\n\nNodeMCU community is rather small and there is already a bunch of tools that supports development in different areas. I started with ESPlorer, but I was missing IDE DX like I have for web development. The thing I actually liked in ESPlorer was colored terminal. I tried coding Lua in VSCode and uploading my program manually using nodemcu-tool, and later using nodemcu-uploader, since it is faster.\nHowever uploading several files to NodeMCU manually was cumbersome, and storing all code just in one source file was unacceptable.\n\nI started working on a simple bundler that would be able to merge all source files into one init.lua, which will be easier to upload. I didn't know about existence of cross compilers then.\n\nI was also missing an ergonomic terminal with some basic features like output coloring and commands history, so I attempt to implement one with Node's transform streams, readline module and serial port library.\n\nThen I quickly bump onto a problem with really limited amount of RAM on ESP boards. Since I uploaded raw .lua files, board has to compile the code to byte code before execution, which turn out to be too greedy for the RAM and basically resulted with VM panic which was restarting the board.\n\nI found out that it's possible to compile Lua code on on PC, before it gets uploaded. It required building Lua cross-compiler, but at the end I didn't have any other choice. I implemented a script that uses previously created bundler, compile a code using cross compiler and finally uploads it to the board, which just one CLI command. Using bundler along with compiler was actually redundant, but Lua module system was strange for me at that moment, and I preferred my bundler.\n\nUploading byte code helped only for a short term, since still the whole program has to be stored in RAM. Around 50kb is too less if you use many sensors which requires some additional libraries. I found out that there is one more thing that I can try to fit my code on NodeMCU. The mechanism called Lua Flash Store that allows to store whole program code in flash memory, so the whole RAM remains free and can be used for program execution. It required building and flashing NodeMCU firmware once again, but it was worth it. Since then, I was not limited by my program length.\n\nHowever, uploading LFS image to NodeMCU is not as straightforward as it could be and requires reiterating on documentation and examples to actually make it work. It also requires 3-step upload process, that is unhandy to be done manually every time. So, as you may guess, I implemented a script...\n\nWith a set of several scripts, I realized that there might be more devs like me, that struggles with lack of convenient NodeMCU tool-chain. So I decided to refactor the whole thing and fit it into this CLI.\n\n## Made with 🧠 by [@jayu](https://github.com/jayu)\n\nI decided to spend some time on bringing all scripts that were serving me well during NodeMCU development into a CLI tool. I hope you will make a good use of it, and it's easy and intuitive. If not, just rise an issue. If this tool was useful, don't hesitate to give it a ⭐!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjayu%2Fnodemcu-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjayu%2Fnodemcu-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjayu%2Fnodemcu-app/lists"}