{"id":14963422,"url":"https://github.com/bcsabaengine/svelteesp32","last_synced_at":"2026-03-13T23:23:44.059Z","repository":{"id":222196797,"uuid":"756065585","full_name":"BCsabaEngine/svelteesp32","owner":"BCsabaEngine","description":"Convert Svelte (or React/Angular/Vue) JS application to serve it from ESP32/ESP8266 webserver","archived":false,"fork":false,"pushed_at":"2026-01-31T22:49:29.000Z","size":1972,"stargazers_count":98,"open_issues_count":4,"forks_count":15,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-02-01T00:57:02.126Z","etag":null,"topics":["angular","arduino","esp-idf","esp32","esp8266","espasyncwebserver","platformio","psychichttp","react","svelte","vue","webserver"],"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/BCsabaEngine.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-02-11T21:44:25.000Z","updated_at":"2026-01-31T22:49:03.000Z","dependencies_parsed_at":"2024-03-11T21:25:00.279Z","dependency_job_id":"e83f4593-289c-411e-b9dd-d0f20f09ccfa","html_url":"https://github.com/BCsabaEngine/svelteesp32","commit_stats":{"total_commits":95,"total_committers":4,"mean_commits":23.75,"dds":"0.052631578947368474","last_synced_commit":"e2e0e4ea5d517c4c05ec3a07a5936074dcb93d08"},"previous_names":["bcsabaengine/svelteesp32"],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/BCsabaEngine/svelteesp32","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BCsabaEngine%2Fsvelteesp32","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BCsabaEngine%2Fsvelteesp32/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BCsabaEngine%2Fsvelteesp32/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BCsabaEngine%2Fsvelteesp32/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BCsabaEngine","download_url":"https://codeload.github.com/BCsabaEngine/svelteesp32/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BCsabaEngine%2Fsvelteesp32/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28977316,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T09:57:52.632Z","status":"ssl_error","status_checked_at":"2026-02-01T09:57:49.143Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":["angular","arduino","esp-idf","esp32","esp8266","espasyncwebserver","platformio","psychichttp","react","svelte","vue","webserver"],"created_at":"2024-09-24T13:31:29.065Z","updated_at":"2026-03-13T23:23:44.048Z","avatar_url":"https://github.com/BCsabaEngine.png","language":"TypeScript","readme":"# svelteesp32 ![image](https://badges.github.io/stability-badges/dist/stable.svg)\n\n### Embed Any Web App in Your ESP32 — One Binary, Zero Filesystem Hassle\n\n**Turn your Svelte, React, Angular, or Vue frontend into a single C++ header file.** Serve beautiful web interfaces directly from ESP32/ESP8266 flash memory with automatic gzip compression, ETag caching, and seamless OTA updates.\n\n[Changelog](CHANGELOG.md)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"svelteesp32.png\" alt=\"svelteesp32\" /\u003e\n\u003c/p\u003e\n\n---\n\n## Why SvelteESP32?\n\n**The problem:** Traditional approaches like SPIFFS and LittleFS require separate partition uploads, complex OTA workflows, and manual compression. Your users end up managing multiple files, and your CI/CD pipeline becomes a mess.\n\n**The solution:** SvelteESP32 compiles your entire web application into a single C++ header file. One firmware binary. One OTA update. Done.\n\n### Key Benefits\n\n- **Single Binary OTA** — Everything embedded in firmware. No partition juggling, no separate uploads.\n- **Automatic Optimization** — Build-time gzip compression with intelligent thresholds (\u003e1KB, \u003e15% reduction).\n- **Smart Caching** — Built-in SHA256 ETags deliver HTTP 304 responses, slashing bandwidth on constrained devices.\n- **CI/CD Ready** — Simple npm package that slots into any build pipeline.\n- **Zero Runtime Overhead** — Data served directly from flash. No filesystem reads, no RAM allocation.\n- **4 Web Server Engines** — PsychicHttpServer V2, ESPAsyncWebServer, Arduino WebServer, and native ESP-IDF supported.\n\n---\n\n## SvelteESP32 vs Traditional Filesystem\n\n| Feature               | SvelteESP32                       | SPIFFS / LittleFS                        |\n| --------------------- | --------------------------------- | ---------------------------------------- |\n| **Single Binary OTA** | ✓ Everything in firmware          | ✗ Separate partition upload required     |\n| **Gzip Compression**  | ✓ Automatic at build time         | Manual or runtime compression            |\n| **ETag Support**      | ✓ Built-in SHA256 + 304 responses | Manual implementation required           |\n| **CI/CD Integration** | ✓ One npm command                 | Complex upload_fs tooling                |\n| **Memory Efficiency** | Flash only (PROGMEM/const arrays) | Filesystem partition + overhead          |\n| **Performance**       | Direct byte array serving         | Filesystem read latency                  |\n| **Setup Complexity**  | Include header, call one function | Partition tables, upload tools, handlers |\n\n**Best for:** Single-binary OTA, CI/CD pipelines, static web UIs that ship with firmware.\n\n**Consider SPIFFS/LittleFS for:** User-uploadable files, runtime-editable configs, dynamic content.\n\n---\n\n## Quick Start\n\n```bash\nnpm install -D svelteesp32\n```\n\nAfter building your frontend (Vite/Rollup/Webpack):\n\n```bash\nnpx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=true\n```\n\nInclude in your ESP32 project:\n\n```c\n#include \u003cPsychicHttp.h\u003e\n#include \"svelteesp32.h\"\n\nPsychicHttpServer server;\n\nvoid setup() {\n    server.listen(80);\n    initSvelteStaticFiles(\u0026server);\n}\n```\n\n**That's it.** Your entire web app is now embedded and ready to serve.\n\n---\n\n## What's New\n\n- **v2.2.2** — `static const` data/ETag arrays prevent multi-TU linker collisions; `SVELTEESP32_MAX_URI_HANDLERS` define added for psychic engine; default exclude patterns removed (now explicit-only)\n- **v2.2.1** — Enhanced `--dryrun` output: engine/ETag/gzip/SPA summary header + aligned route table with MIME types, sizes, and tags (`[default]`, `[no gzip]`, `[SPA catch-all]`)\n- **v2.2.0** — SPA routing catch-all (`--spa`) for client-side routers on all four engines\n- **v2.1.0** — New Arduino WebServer engine (`-e webserver`), dependency updates\n- **v2.0.0** — **BREAKING**: PsychicHttpServer V2 is now the default `psychic` engine. The `psychic2` engine has been removed. Dry run mode, C++ identifier validation, improved MIME type warnings\n- **v1.16.0** — Size budget constraints (`--maxsize`, `--maxgzipsize`)\n- **v1.15.0** — `--basepath` for multiple frontends (e.g., `/admin`, `/app`)\n- **v1.13.0** — npm package variable interpolation in RC files\n- **v1.12.0** — RC file configuration support\n- **v1.11.0** — File exclusion patterns\n- **v1.9.0** — Native ESP-IDF engine\n\n---\n\n## Requirements\n\n- Node.js \u003e= 20\n- npm \u003e= 9\n\n---\n\n## Installation \u0026 Usage\n\n### Install\n\n```bash\nnpm install -D svelteesp32\n```\n\n### Generate Header File\n\nChoose your web server engine:\n\n```bash\n# PsychicHttpServer (recommended for ESP32)\nnpx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=true\n\n# ESPAsyncWebServer (ESP32 + ESP8266)\nnpx svelteesp32 -e async -s ./dist -o ./esp32/svelteesp32.h --etag=true\n\n# Arduino WebServer (ESP32, synchronous, no dependencies)\nnpx svelteesp32 -e webserver -s ./dist -o ./esp32/svelteesp32.h --etag=true\n\n# Native ESP-IDF\nnpx svelteesp32 -e espidf -s ./dist -o ./esp32/svelteesp32.h --etag=true\n```\n\n### Build Output\n\nWatch your files get optimized in real-time:\n\n```\n[assets/index-KwubEIf-.js]  ✓ gzip used (38850 -\u003e 12547 = 32%)\n[assets/index-Soe6cpLA.css] ✓ gzip used (32494 -\u003e 5368 = 17%)\n[favicon.png]               x gzip unused (33249 -\u003e 33282 = 100%)\n[index.html]                x gzip unused (too small) (472 -\u003e 308 = 65%)\n[roboto_regular.json]       ✓ gzip used (363757 -\u003e 93567 = 26%)\n\n5 files, 458kB original size, 142kB gzip size\n../../../Arduino/EspSvelte/svelteesp32.h 842kB size\n```\n\n**Automatic optimizations:**\n\n- Gzip level 9 compression when beneficial (\u003e1KB, \u003e15% size reduction)\n- Duplicate file detection via SHA256 hashing\n- Smart skip of pre-compressed files (.gz, .br) when originals exist\n\n### ESP32 Integration\n\n**PsychicHttpServer V2 (Recommended)**\n\n```c\n#include \u003cPsychicHttp.h\u003e\n#include \"svelteesp32.h\"\n\nPsychicHttpServer server;\n\nvoid setup() {\n    server.listen(80);\n    initSvelteStaticFiles(\u0026server);  // One line. Done.\n}\n```\n\n**ESPAsyncWebServer**\n\n```c\n#include \u003cESPAsyncWebServer.h\u003e\n#include \"svelteesp32.h\"\n\nAsyncWebServer server(80);\n\nvoid setup() {\n    initSvelteStaticFiles(\u0026server);\n    server.begin();\n}\n```\n\n**Arduino WebServer (built-in, no dependencies)**\n\n```c\n#include \u003cWebServer.h\u003e\n#include \"svelteesp32.h\"\n\nWebServer server(80);\n\nvoid setup() {\n    initSvelteStaticFiles(\u0026server);\n    server.begin();\n}\n\nvoid loop() {\n    server.handleClient();\n}\n```\n\n**Native ESP-IDF**\n\n```c\n#include \u003cesp_http_server.h\u003e\n#include \"svelteesp32.h\"\n\nhttpd_handle_t server = NULL;\n\nvoid app_main() {\n    httpd_config_t config = HTTPD_DEFAULT_CONFIG();\n    httpd_start(\u0026server, \u0026config);\n    initSvelteStaticFiles(server);\n}\n```\n\nWorking examples with LED control via web interface: [Arduino/PlatformIO](demo/esp32) | [ESP-IDF](demo/esp32idf)\n\n### What Gets Generated\n\nThe generated header file includes everything your ESP needs:\n\n```c\n//engine:   PsychicHttpServer V2\n//config:   engine=psychic sourcepath=./dist outputfile=./output.h etag=true gzip=true cachetime=0 espmethod=initSvelteStaticFiles define=SVELTEESP32\n//\n#define SVELTEESP32_COUNT 5\n#define SVELTEESP32_SIZE 468822\n#define SVELTEESP32_SIZE_GZIP 145633\n#define SVELTEESP32_FILE_INDEX_HTML\n#define SVELTEESP32_HTML_FILES 1\n#define SVELTEESP32_CSS_FILES 1\n#define SVELTEESP32_JS_FILES 1\n...\n\n#include \u003cArduino.h\u003e\n#include \u003cPsychicHttp.h\u003e\n#include \u003cPsychicHttpsServer.h\u003e\n\nconst uint8_t datagzip_assets_index_KwubEIf__js[12547] = {0x1f, 0x8b, 0x8, 0x0, ...\nconst uint8_t datagzip_assets_index_Soe6cpLA_css[5368] = {0x1f, 0x8b, 0x8, 0x0, 0x0, ...\nconst char * etag_assets_index_KwubEIf__js = \"387b88e345cc56ef9091...\";\nconst char * etag_assets_index_Soe6cpLA_css = \"d4f23bc45ef67890ab12...\";\n\n// File manifest for runtime introspection\nstruct SVELTEESP32_FileInfo {\n  const char* path;\n  uint32_t size;\n  uint32_t gzipSize;\n  const char* etag;\n  const char* contentType;\n};\nconst SVELTEESP32_FileInfo SVELTEESP32_FILES[] = {\n  { \"/assets/index-KwubEIf-.js\", 38850, 12547, etag_assets_index_KwubEIf__js, \"text/javascript\" },\n  { \"/assets/index-Soe6cpLA.css\", 32494, 5368, etag_assets_index_Soe6cpLA_css, \"text/css\" },\n  ...\n};\nconst size_t SVELTEESP32_FILE_COUNT = sizeof(SVELTEESP32_FILES) / sizeof(SVELTEESP32_FILES[0]);\n...\n\n// File served hook - override with your own implementation for metrics/logging\nextern \"C\" void __attribute__((weak)) SVELTEESP32_onFileServed(const char* path, int statusCode) {}\n\nvoid initSvelteStaticFiles(PsychicHttpServer * server) {\n  server-\u003eon(\"/assets/index-KwubEIf-.js\", HTTP_GET, [](PsychicRequest * request, PsychicResponse * response) {\n    if (request-\u003ehasHeader(\"If-None-Match\") \u0026\u0026\n        request-\u003eheader(\"If-None-Match\").equals(etag_assets_index_KwubEIf__js)) {\n      response-\u003esetCode(304);\n      SVELTEESP32_onFileServed(\"/assets/index-KwubEIf-.js\", 304);\n      return response-\u003esend();\n    }\n\n    response-\u003esetContentType(\"text/javascript\");\n    response-\u003eaddHeader(\"Content-Encoding\", \"gzip\");\n    response-\u003eaddHeader(\"Cache-Control\", \"no-cache\");\n    response-\u003eaddHeader(\"ETag\", etag_assets_index_KwubEIf__js);\n    response-\u003esetContent(datagzip_assets_index_KwubEIf__js, 12547);\n    SVELTEESP32_onFileServed(\"/assets/index-KwubEIf-.js\", 200);\n    return response-\u003esend();\n  });\n\n  // ... more routes\n}\n```\n\n---\n\n## Supported Web Server Engines\n\n| Engine                   | Flag           | Best For                     | Platform        |\n| ------------------------ | -------------- | ---------------------------- | --------------- |\n| **PsychicHttpServer V2** | `-e psychic`   | Maximum performance          | ESP32 only      |\n| **ESPAsyncWebServer**    | `-e async`     | Cross-platform compatibility | ESP32 + ESP8266 |\n| **Arduino WebServer**    | `-e webserver` | No dependencies, simplicity  | ESP32 only      |\n| **Native ESP-IDF**       | `-e espidf`    | Pure ESP-IDF projects        | ESP32 only      |\n\n**Recommendation:** For ESP32-only projects, use PsychicHttpServer V2 (`-e psychic`) for the fastest, most stable experience.\n\n**Note:** For PsychicHttp, configure `server.config.max_uri_handlers`. The generated header provides `SVELTEESP32_MAX_URI_HANDLERS` (file count + 5 safety margin) for use directly in your sketch.\n\n---\n\n## Features\n\n### Automatic Gzip Compression\n\nYour JS, CSS, and HTML files are automatically compressed at build time — not on the ESP32. Files are gzipped when they're \u003e1KB and achieve \u003e15% size reduction.\n\n- **Enabled by default** — disable with `--gzip=false`\n- **Compiler mode** — use `--gzip=compiler` and control via `-D SVELTEESP32_ENABLE_GZIP` in PlatformIO\n\n### Smart ETag Caching\n\nReduce bandwidth dramatically with HTTP 304 \"Not Modified\" responses. When a browser has a cached file, the ESP32 sends just a status code instead of the entire file — perfect for bandwidth-constrained IoT devices.\n\n- **Enable with** `--etag=true` (recommended)\n- **Minimal overhead** — adds ~1-3% code size for significant bandwidth savings\n- **Compiler mode** — use `--etag=compiler` and control via `-D SVELTEESP32_ENABLE_ETAG`\n\nAll four engines support full ETag validation.\n\n### Browser Cache Control\n\nFine-tune how browsers cache your content:\n\n- **Default:** `no-cache` — browsers always validate with server (ETag check)\n- **Long-term caching:** `--cachetime=86400` — cache for 24 hours without any server requests\n\n### Automatic Index Handling\n\nYour `index.html` is automatically served at the root URL — just like any web server. Visit `http://esp32.local/` and your app loads.\n\n**API-only projects?** Skip index validation with `--noindexcheck`:\n\n```bash\nnpx svelteesp32 -e psychic -s ./dist -o ./output.h --noindexcheck\n```\n\n### File Exclusion\n\nKeep source maps, docs, and test files out of your firmware:\n\n```bash\n# Single pattern\nnpx svelteesp32 -s ./dist -o ./output.h --exclude=\"*.map\"\n\n# Multiple patterns\nnpx svelteesp32 -s ./dist -o ./output.h --exclude=\"*.map,*.md,test/**/*\"\n```\n\nNo patterns are excluded by default — specify everything you need explicitly.\n\nBuild output shows exactly what's excluded:\n\n```\nExcluded 3 file(s):\n  - assets/index.js.map\n  - assets/vendor.js.map\n  - README.md\n```\n\n### Multiple Frontends (Base Path)\n\nServe multiple web apps from one ESP32 using URL prefixes:\n\n```bash\nnpx svelteesp32 -s ./admin-dist -o ./admin.h --basepath=/admin\nnpx svelteesp32 -s ./user-dist -o ./user.h --basepath=/app\n```\n\n```c\n#include \"admin.h\"  // Serves at /admin/*\n#include \"user.h\"   // Serves at /app/*\n\nvoid setup() {\n    server.listen(80);\n    initSvelteStaticFiles_admin(\u0026server);\n    initSvelteStaticFiles_user(\u0026server);\n    server.on(\"/api/data\", HTTP_GET, handleApiData);\n}\n```\n\n**Rules:** Must start with `/`, no trailing slash, no double slashes.\n\n### SPA Routing (Client-Side Routers)\n\nModern JS frameworks use client-side routing. Without a catch-all, refreshing `/settings` on your ESP32 returns nothing. Add `--spa` to make all unmatched GET requests fall through to `index.html`:\n\n```bash\nnpx svelteesp32 -e async -s ./dist -o ./output.h --spa\nnpx svelteesp32 -e psychic -s ./dist -o ./output.h --spa --basepath=/app\n```\n\nWhat gets generated per engine:\n\n| Engine      | Catch-all mechanism                                                                                                          |\n| ----------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| `psychic`   | `server-\u003eon(\"/*\", ...)` (no basePath) already handled by `defaultEndpoint`; `server-\u003eon(\"/app/*\", ...)` when basePath is set |\n| `async`     | `server-\u003eonNotFound(...)` with optional basePath prefix check                                                                |\n| `webserver` | `server-\u003eonNotFound(...)` with optional basePath prefix check                                                                |\n| `espidf`    | `httpd_register_err_handler(HTTPD_404_NOT_FOUND, ...)`                                                                       |\n\n**Note:** `--spa` requires `index.html` or `index.htm` in the source directory — a warning is printed if it is missing.\n\n### C++ Build-Time Validation\n\nCatch configuration issues at compile time with generated defines:\n\n```c\n#include \"svelteesp32.h\"\n\n#if SVELTEESP32_COUNT != 5\n  #error Unexpected file count - check your build\n#endif\n\n#ifndef SVELTEESP32_FILE_INDEX_HTML\n  #error Missing index.html - frontend build failed?\n#endif\n```\n\n**Available defines:** `SVELTEESP32_COUNT`, `SVELTEESP32_SIZE`, `SVELTEESP32_SIZE_GZIP`, `SVELTEESP32_FILE_*`, `SVELTEESP32_*_FILES`\n\n### Runtime File Manifest\n\nQuery embedded files at runtime for logging, diagnostics, or API endpoints:\n\n```c\n// List all embedded files\nfor (size_t i = 0; i \u003c SVELTEESP32_FILE_COUNT; i++) {\n    const auto\u0026 f = SVELTEESP32_FILES[i];\n    Serial.printf(\"%s (%d bytes, gzip: %d)\\n\", f.path, f.size, f.gzipSize);\n}\n```\n\nEach file entry includes: `path`, `size`, `gzipSize`, `etag`, `contentType`\n\n### Request Hook (Metrics \u0026 Logging)\n\nTrack every request with zero overhead when unused (weak linkage):\n\n```c\nextern \"C\" void SVELTEESP32_onFileServed(const char* path, int statusCode) {\n    Serial.printf(\"[HTTP] %s -\u003e %d\\n\", path, statusCode);\n    if (statusCode == 304) cacheHits++;\n}\n```\n\nCalled for every response (200 = content served, 304 = cache hit).\n\n---\n\n## CLI Reference\n\n| Option           | Description                                         | Default                 |\n| ---------------- | --------------------------------------------------- | ----------------------- |\n| `-s`             | Source folder with compiled web files               | (required)              |\n| `-e`             | Web server engine (psychic/async/espidf/webserver)  | `psychic`               |\n| `-o`             | Output header file path                             | `svelteesp32.h`         |\n| `--etag`         | ETag caching (true/false/compiler)                  | `false`                 |\n| `--gzip`         | Gzip compression (true/false/compiler)              | `true`                  |\n| `--exclude`      | Exclude files by glob pattern                       | System files            |\n| `--basepath`     | URL prefix for all routes                           | (none)                  |\n| `--maxsize`      | Max total uncompressed size (e.g., `400k`, `1m`)    | (none)                  |\n| `--maxgzipsize`  | Max total gzip size (e.g., `150k`, `500k`)          | (none)                  |\n| `--cachetime`    | Cache-Control max-age in seconds                    | `0`                     |\n| `--version`      | Version string in header                            | (none)                  |\n| `--define`       | C++ define prefix                                   | `SVELTEESP32`           |\n| `--espmethod`    | Init function name                                  | `initSvelteStaticFiles` |\n| `--config`       | Custom RC file path                                 | `.svelteesp32rc.json`   |\n| `--dryrun`       | Show route table + summary without writing output   | `false`                 |\n| `--spa`          | Serve index.html for unmatched routes (SPA routing) | `false`                 |\n| `--noindexcheck` | Skip index.html validation                          | `false`                 |\n| `-h`             | Show help                                           |                         |\n\n---\n\n## Configuration File\n\nStore your settings in `.svelteesp32rc.json` for zero-argument builds:\n\n```json\n{\n  \"engine\": \"psychic\",\n  \"sourcepath\": \"./dist\",\n  \"outputfile\": \"./esp32/svelteesp32.h\",\n  \"etag\": \"true\",\n  \"gzip\": \"true\",\n  \"exclude\": [\"*.map\", \"*.md\"],\n  \"basepath\": \"/ui\",\n  \"maxsize\": \"400k\",\n  \"maxgzipsize\": \"150k\",\n  \"noindexcheck\": false,\n  \"dryrun\": false,\n  \"spa\": false\n}\n```\n\nThen just run:\n\n```bash\nnpx svelteesp32\n```\n\n### npm Variable Interpolation\n\nSync versions and names automatically from your `package.json`:\n\n```json\n{\n  \"version\": \"v$npm_package_version\",\n  \"define\": \"$npm_package_name\"\n}\n```\n\nWith `package.json` containing `\"version\": \"2.1.0\"`, this becomes `\"version\": \"v2.1.0\"`.\n\n### Multiple Environments\n\n```bash\nnpx svelteesp32 --config=.svelteesp32rc.prod.json\n```\n\nCLI arguments always override RC file values.\n\n---\n\n## FAQ\n\n**How large can my web app be?**\nWith gzip compression, 3-4MB asset directories work comfortably. That's enough for a full-featured SPA.\n\n**Does this use RAM or Flash?**\nFlash only. Data is stored in program memory (PROGMEM on ESP8266, const arrays on ESP32), leaving your heap and stack free for application logic.\n\n**Why is the .h file so large?**\nThe text representation (comma-separated bytes) is larger than binary. Check `SVELTEESP32_SIZE_GZIP` for actual flash usage.\n\n**Does compilation take forever?**\nNo. Large headers compile in seconds, and incremental builds skip recompilation if your frontend hasn't changed.\n\n**Can frontend and firmware teams work separately?**\nAbsolutely. Frontend builds the app, runs svelteesp32, commits the header. Firmware team includes it and ships. Version sync via npm variables keeps everyone aligned.\n\n---\n\n## Development\n\n```bash\nnpm run build        # Build TypeScript\nnpm run test         # Run unit tests\nnpm run test:watch   # Watch mode\nnpm run fix          # Fix formatting \u0026 linting\n```\n\n---\n\n**Ready to ship your web UI in a single binary?**\n\n```bash\nnpm install -D svelteesp32\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcsabaengine%2Fsvelteesp32","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbcsabaengine%2Fsvelteesp32","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcsabaengine%2Fsvelteesp32/lists"}