MCPcopy Index your code
hub / github.com/BCsabaEngine/svelteesp32

github.com/BCsabaEngine/svelteesp32 @v3.1.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release v3.1.3 ↗ · + Follow
108 symbols 329 edges 40 files 1 documented · 1%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

svelteesp32 image

Embed Any Web App in Your ESP32 — One Binary, Zero Filesystem Hassle

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.

Changelog

svelteesp32


Why SvelteESP32?

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.

The solution: SvelteESP32 compiles your entire web application into a single C++ header file. One firmware binary. One OTA update. Done.

Key Benefits

  • Single Binary OTA — Everything embedded in firmware. No partition juggling, no separate uploads.
  • Automatic Optimization — Build-time gzip compression with intelligent thresholds (>1KB, >15% reduction).
  • Smart Caching — Built-in SHA256 ETags deliver HTTP 304 responses, slashing bandwidth on constrained devices.
  • CI/CD Ready — Simple npm package that slots into any build pipeline.
  • Zero Runtime Overhead — Data served directly from flash. No filesystem reads, no RAM allocation.
  • 4 Web Server Engines — PsychicHttpServer V2, ESPAsyncWebServer, Arduino WebServer, and native ESP-IDF supported.

SvelteESP32 vs Traditional Filesystem

Feature SvelteESP32 SPIFFS / LittleFS
Single Binary OTA ✓ Everything in firmware ✗ Separate partition upload required
Gzip Compression ✓ Automatic at build time Manual or runtime compression
ETag Support ✓ Built-in SHA256 + 304 responses Manual implementation required
CI/CD Integration ✓ One npm command Complex upload_fs tooling
Memory Efficiency Flash only (PROGMEM/const arrays) Filesystem partition + overhead
Performance Direct byte array serving Filesystem read latency
Setup Complexity Include header, call one function Partition tables, upload tools, handlers

Best for: Single-binary OTA, CI/CD pipelines, static web UIs that ship with firmware.

Consider SPIFFS/LittleFS for: User-uploadable files, runtime-editable configs, dynamic content.


Quick Start

npm install -D svelteesp32

After building your frontend (Vite/Rollup/Webpack):

npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=always

Include in your ESP32 project:

#include <PsychicHttp.h>
#include "svelteesp32.h"

PsychicHttpServer server;

void setup() {
    server.listen(80);
    initSvelteStaticFiles(&server);
}

That's it. Your entire web app is now embedded and ready to serve.

Just want production-safe defaults?

bash npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h \ --etag=always --gzip=always --cachetimehtml=0 --cachetimeassets=31536000

ETags for instant 304s, gzip for smaller transfers, no-cache for HTML so updates are always picked up, and 1-year caching for content-hashed JS/CSS assets.


What's New

  • v3.1.0 — Removed handlebars, picomatch, and mime-types dependencies; C++ generation is now pure TypeScript with a built-in MIME type map and direct tinyglobby exclude handling. --cachetime-html--cachetimehtml, --cachetime-assets--cachetimeassets (CLI now matches RC file keys); --dry-run alias removed — use --dryrun. SVELTEESP32_URI_HANDLERS/SVELTEESP32_MAX_URI_HANDLERS (psychic/espidf) now reflect the exact registered route count, including the default / route and --spa catch-all
  • v3.0.0Vite plugin (import { svelteESP32 } from 'svelteesp32/vite') generates the header automatically after every build — call with no argument for RC file mode or pass an options object for plugin-options mode; npx svelteesp32 init interactive RC file wizard; Node.js >= 22 required
  • v2.4.0--analyze for CI size budget checks (per-file table, exits 1 on over-budget); --manifest to write a companion JSON manifest alongside the header
  • v2.3.0--cachetimehtml and --cachetimeassets for per-type cache control (e.g. no-cache for HTML, 1-year for content-hashed JS/CSS)
  • v2.2.0 — SPA routing catch-all (--spa) for client-side routers on all four engines
  • v2.1.0 — New Arduino WebServer engine (-e webserver), dependency updates
  • v2.0.0BREAKING: PsychicHttpServer V2 is now the default psychic engine. The psychic2 engine has been removed. Dry run mode, C++ identifier validation, improved MIME type warnings
  • v1.16.0 — Size budget constraints (--maxsize, --maxgzipsize)
  • v1.15.0--basepath for multiple frontends (e.g., /admin, /app)
  • v1.13.0 — npm package variable interpolation in RC files
  • v1.12.0 — RC file configuration support
  • v1.11.0 — File exclusion patterns
  • v1.9.0 — Native ESP-IDF engine

Requirements

  • Node.js >= 22
  • npm >= 10

Installation & Usage

Install

npm install -D svelteesp32

Quick Setup with init

The init command creates a .svelteesp32rc.json configuration file interactively so you never have to remember CLI flags:

npx svelteesp32 init

It asks for engine, source path, output path, and ETag preference, writes the RC file, and optionally runs the tool immediately.

Vite Plugin

For Vite-based projects (SvelteKit, React, Vue, Vanilla) you can skip the manual CLI step entirely — the plugin hooks into the build pipeline and regenerates the C++ header automatically after every vite build.

The plugin has two exclusive modes — pick one:

RC file mode — call with no argument (or a string path to a custom RC file). All settings come from .svelteesp32rc.json; outputfile in the RC file is required.

import { svelteKit } from '@sveltejs/kit/vite';
import { svelteESP32 } from 'svelteesp32/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    svelteKit(),
    svelteESP32() // auto-discover .svelteesp32rc.json
    // svelteESP32('/path/to/custom.rc.json')  // or specify path explicitly
  ]
});

Plugin options mode — call with an options object. The RC file is completely ignored; output is required.

export default defineConfig({
  plugins: [
    svelteKit(),
    svelteESP32({
      output: '../firmware/include/svelteesp32.h',
      engine: 'psychic',
      etag: 'always',
      gzip: 'always',
      cachetimehtml: 0,
      cachetimeassets: 31536000
    })
  ]
});

sourcepath defaults to Vite's build.outDir in both modes.

Plugin options

Option Type Default Description
output string RC outputfile Output .h file path
sourcepath string Vite's build.outDir Source directory (compiled web files)
engine 'psychic'\|'async'\|'espidf'\|'webserver' 'psychic' Target web server engine
etag 'always'\|'never'\|'compiler' 'never' ETag generation mode
gzip 'always'\|'never'\|'compiler' 'always' Gzip compression mode
cachetime number 0 Cache-Control: max-age in seconds (all files)
cachetimehtml number (unset) max-age for HTML files (overrides cachetime)
cachetimeassets number (unset) max-age for non-HTML files (overrides cachetime)
exclude string[] [] Glob patterns to exclude
basepath string (none) URL prefix for all routes
espmethod string 'initSvelteStaticFiles' Generated init function name
define string 'SVELTEESP32' C++ #define prefix
version string (none) Version string embedded in header
created boolean false Include creation timestamp
spa boolean false Serve index.html for unmatched routes
manifest boolean false Write companion .manifest.json
noindexcheck boolean false Skip index.html validation
maxsize number (none) Max total uncompressed size in bytes
maxgzipsize number (none) Max total gzip size in bytes

Generate Header File (CLI)

Choose your web server engine:

# PsychicHttpServer (recommended for ESP32)
npx svelteesp32 -e psychic -s ./dist -o ./esp32/svelteesp32.h --etag=always

# ESPAsyncWebServer (ESP32 + ESP8266)
npx svelteesp32 -e async -s ./dist -o ./esp32/svelteesp32.h --etag=always

# Arduino WebServer (ESP32, synchronous, no dependencies)
npx svelteesp32 -e webserver -s ./dist -o ./esp32/svelteesp32.h --etag=always

# Native ESP-IDF
npx svelteesp32 -e espidf -s ./dist -o ./esp32/svelteesp32.h --etag=always

Build Output

Watch your files get optimized in real-time:

[assets/index-KwubEIf-.js]  ✓ gzip used (38850 -> 12547 = 32%)
[assets/index-Soe6cpLA.css] ✓ gzip used (32494 -> 5368 = 17%)
[favicon.png]               x gzip unused (33249 -> 33282 = 100%)
[index.html]                x gzip unused (too small) (472 -> 308 = 65%)
[roboto_regular.json]       ✓ gzip used (363757 -> 93567 = 26%)

5 files, 458kB original size, 142kB gzip size
../../../Arduino/EspSvelte/svelteesp32.h 842kB size

Automatic optimizations:

  • Gzip level 9 compression when beneficial (>1KB, >15% size reduction)
  • Duplicate file detection via SHA256 hashing
  • Smart skip of pre-compressed files (.gz, .br) when originals exist

ESP32 Integration

PsychicHttpServer V2 (Recommended)

#include <PsychicHttp.h>
#include "svelteesp32.h"

PsychicHttpServer server;

void setup() {
    server.listen(80);
    initSvelteStaticFiles(&server);  // One line. Done.
}

ESPAsyncWebServer

#include <ESPAsyncWebServer.h>
#include "svelteesp32.h"

AsyncWebServer server(80);

void setup() {
    initSvelteStaticFiles(&server);
    server.begin();
}

Arduino WebServer (built-in, no dependencies)

#include <WebServer.h>
#include "svelteesp32.h"

WebServer server(80);

void setup() {
    initSvelteStaticFiles(&server);
    server.begin();
}

void loop() {
    server.handleClient();
}

Native ESP-IDF

#include <esp_http_server.h>
#include "svelteesp32.h"

httpd_handle_t server = NULL;

void app_main() {
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    httpd_start(&server, &config);
    initSvelteStaticFiles(server);
}

Working examples with LED control via web interface: Arduino/PlatformIO | ESP-IDF

What Gets Generated

The generated header file includes everything your ESP needs:

```c //engine: PsychicHttpServer V2 //config: engine=psychic sourcepath=./dist outputfile=./output.h etag=always gzip=always cachetime=0 espmethod=initSvelteStaticFiles define=SVELTEESP32 //

define SVELTEESP32_COUNT 5

define SVELTEESP32_SIZE 468822

define SVELTEESP32_SIZE_GZIP 145633

define SVELTEESP32_FILE_INDEX_HTML

define SVELTEESP32_HTML_FILES 1

define SVELTEESP32_CSS_FILES 1

define SVELTEESP32_JS_FILES 1

...

include

include

include

static const uint8_t datagzip_assets_index_KwubEIf__js[12547] = {0x1f, 0x8b, 0x8, 0x0, ... static const uint8_t datagzip_assets_index_Soe6cpLA_css[5368] = {0x1f, 0x8b, 0x8, 0x0, 0x0, ... static const char etag_assets_index_KwubEIf__js[] = "387b88e345cc56ef9091..."; static const char etag_assets_index_Soe6cpLA_css[] = "d4f23bc45ef67890ab12...";

// File manifest for runtime introspection struct SVELTEESP32_FileInfo { const char path; uint32_t size; uint32_t gzipSize; const char etag; const char* contentType; }; const SVELTEESP32_FileInfo SVELTEESP32_FILES[] = { { "/assets/index-KwubEIf-.js", 38850, 12547, etag_assets_index_KwubEIf__js, "text/javascript" }, { "/assets/index-Soe6cpLA.css", 32494, 5368, etag_assets_index_Soe6cpLA_css, "text/css" }, ... }; const size_t SVELTEESP32_FILE_COUNT = si

Extension points exported contracts — how you extend this code

ResolvedViteConfig (Interface)
(no doc)
src/vitePlugin.ts
ICopyFilesArguments (Interface)
(no doc)
src/commandLine.ts
VitePlugin (Interface)
(no doc)
src/vitePlugin.ts
IRcFileConfig (Interface)
(no doc)
src/commandLine.ts
SvelteESP32PluginOptions (Interface)
(no doc)
src/vitePlugin.ts

Core symbols most depended-on inside this repo

getCppCode
called by 160
src/cppCode.ts
parseArguments
called by 125
src/commandLine.ts
main
called by 41
src/index.ts
createSourceEntry
called by 24
src/pipeline.ts
getFiles
called by 22
src/file.ts
sw
called by 22
src/cppCode.ts
svelteESP32
called by 21
src/vitePlugin.ts
formatConfig
called by 20
src/commandLine.ts

Shape

Function 100
Interface 5
Class 2
Method 1

Languages

TypeScript85%
C++8%
C6%

Modules by API surface

src/commandLine.ts24 symbols
src/pipeline.ts16 symbols
src/cppCode.ts13 symbols
src/vitePlugin.ts7 symbols
demo/esp32idf/src/main.c7 symbols
src/errorMessages.ts5 symbols
src/consoleColor.ts4 symbols
src/initCommand.ts3 symbols
src/file.ts3 symbols
demo/esp32/src/main_webserver.cpp3 symbols
demo/esp32/src/main_psychic.cpp3 symbols
demo/esp32/src/main_async.cpp3 symbols

For agents

$ claude mcp add svelteesp32 \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact