euler

Euler brings Innernet, Quitter, and Instants into one local workspace at http://localhost:2713.

Type: Project. Something quirq builds for people to use.TypeScriptUpdated Oct 4

Euler's customizable blob avatar

Euler

Your apps. One home. One dock.

Cross-platform checks

Euler brings Innernet, Quitter, and Instants into one local workspace at http://localhost:2713. Switch apps from a floating dock, turn them on or off, and make Euler your own with a customizable avatar.

Quick start · How it works · Deploy · Development · Data and settings

Euler Home with app status, lifecycle controls, avatar editor, and floating dock

Home brings app status, launch controls, enabled settings, and the avatar editor together. Saving an avatar updates Euler's logo and the dock's Home icon; app icons keep their identities.

Quick start

Install Node.js 24 and Git. Node 22.13 or newer is supported. These commands work on Windows, macOS, and Linux:

sh
git clone https://github.com/quirq-ai/euler.git
cd euler
npm ci
npm run setup
npm run build
npm start

Open http://localhost:2713. All three bundled apps are enabled initially; Home stays available. Stop Euler with Ctrl+C in its terminal; closing the browser tab leaves it running.

StepWhat it does
npm ciInstalls the root Nx and package-manager tools.
npm run setupInstalls the bundled apps from their committed lockfiles; Home needs no dependencies.
npm run buildValidates Home and compiles enabled apps for their /app/<name> routes.
npm startStarts one HTTP server and mounts the enabled builds.

The app sources and routing changes are already included. No sibling repositories or patch-preparation step is required. For another port, use npm start -- --port 2800.

How it works

mermaid
flowchart TB
Browser["Browser · localhost:2713"] --> Euler["Euler · one Node.js server"]
Euler --> Home["Home /<br/>App status + controls + avatar editor"]
Euler --> Innernet["/app/innernet<br/>Next.js pages + APIs"]
Euler --> Quitter["/app/quitter/<br/>Built Vite app"]
Euler --> Instants["/app/instants<br/>Next.js pages + APIs"]
Dock["Shared floating dock<br/>Home · running apps · opacity"] -. "on every page" .-> Home
Dock -.-> Innernet
Dock -.-> Quitter
Dock -.-> Instants
style Euler fill:#dceaff,stroke:#5b82bc,color:#14253f
style Dock fill:#e9e4fa,stroke:#8978b6,color:#302547

Apps render directly under Euler's address. Their page, asset, and API URLs stay within their own prefix; for example, Innernet's suggestions endpoint is /app/innernet/api/suggest. Euler dispatches to prepared Next.js handlers or built static files inside the same process.

The dock is added to HTML pages. API responses, assets, and React server component streams retain their original content. Switching uses normal links, enhanced by native document transitions where supported. The dock remembers each tab's last app route and window scroll position; arbitrary unsaved forms or component state may reset when navigating.

Use the workspace

ControlBehavior
HomeSee app status and counts, launch and manage apps, and customize Euler's avatar.
Dock appearanceAdjust the glass background opacity from 20–100%.
App On / Off switchApply availability immediately and remember it for startup and default builds.
SettingsEdit Enable in Euler, then choose Save settings to apply it.
Start / StopMount or unmount an app's existing build.
RestartReactivate the prepared build. Source changes still require rebuilding.
LogsInspect recent lifecycle output and errors.
Start enabled / Stop allControl the workspace's app routes together.
Search and filtersFind apps by name or show running, enabled, or stopped apps.

Each app's status dot and controls are together on Home. Enabled settings persist across sessions; stopping an app affects its current running state. The dock shows running apps and stays available on Home and app pages. Older /manage links redirect to the applications section on Home.

Choose Personalize or expand Make Euler yours. below the apps to open the avatar editor. App refreshes preserve any avatar draft you are editing.

Use Alt+0 for Home, Alt+1…9 for running apps, and arrow keys to move between focused dock items. Reduced-motion preferences are respected.

Apps can also supply their own dock style or interface while sharing Euler's running-app state and navigation. See per-app docks for configuration, the module API, and a working example. Home keeps its standard dock.

Deployment

Choose whether you need the complete Euler workspace or an independently hosted app. The current Euler host is designed for loopback access and local persistent storage. The deployment options below reflect that implementation.

DestinationWhat works with this repositoryInstructions
Your Windows, macOS, or Linux machineComplete Euler workspaceQuick start
Linux VM / VPS with SSH and persistent diskComplete Euler workspace through a private SSH tunnelFull Euler on a server
VercelSeparate Quitter, Innernet demo, and Instants browser-session deploymentsVercel
Netlify / Cloudflare PagesStandalone Quitter static appStatic hosts
Public container/PaaS servicesFull Euler needs a hosting adapter firstPublic hosting limits

Full Euler on a Linux server

Use a persistent Linux VM with Node 24, Git, and SSH access: for example, a DigitalOcean Droplet, Hetzner VM, AWS EC2 instance, or your own Linux server. Run as a normal account. Innernet indexes files on that server, not files on the computer viewing it.

  1. Connect over SSH and run the quick-start commands on the server. Keep Euler's port bound to loopback.

  2. In a terminal on your own computer, open a tunnel:

    sh
    ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:2713:127.0.0.1:2713 user@your-server
  3. Browse http://127.0.0.1:2713 on your computer. Keep the tunnel open while using Euler. You only need SSH exposed by the server; port 2713 stays private.

The forwarded port must match Euler's configured port because its request checks include the port. Stop another local Euler instance before opening this tunnel, or choose the same alternate port on both ends. See OpenSSH local forwarding.

Keep Euler running with systemd

On a Linux system with a systemd user session, first stop any foreground Euler process. Run the following from the built repository's root. The unit captures the current checkout and Node paths, including version-manager installations:

sh
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/euler.service <<EOF
[Unit]
Description=Euler app workspace
After=network.target
[Service]
Type=simple
WorkingDirectory=$PWD
ExecStart="$(command -v node)" "$PWD/bin/euler.mjs"
Environment=NODE_ENV=production
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now euler

To keep the user service running after logout, an administrator can enable lingering for your account:

sh
sudo loginctl enable-linger "$(id -un)"

Useful commands:

sh
systemctl --user status euler
journalctl --user -u euler -f
systemctl --user stop euler
systemctl --user start euler

If you change the Node installation path, regenerate the unit and reload it. Reference: systemd service units.

For updates, stop the service, run git pull --ff-only, npm ci, npm run setup, and npm run build in the checkout, then start the service. Preserve the data directories across updates and backups.

Vercel: individual apps

The complete Euler host is not currently supported as a Vercel deployment by this repository. The app folders can be deployed as separate Vercel projects. Each gets its own URL and standalone app behavior; the Euler Home, shared dock, and host controls are not part of those deployments.

Import quirq-ai/euler once for each app you want. Select production branch main, Node 24.x, and the following settings. Root Directory is relative to the Git repository; build/output paths are relative to that app directory.

AppRoot DirectoryFrameworkInstall commandBuild commandOutput
Quitterapp/quitterVitenpm cinpm run builddist
Innernetapp/innernetNext.jsnpx --yes pnpm@9.12.3 install --frozen-lockfilenpm run buildNext.js default
Instantsapp/instantsNext.jsnpm cinpm run buildNext.js default

Use each app's build script, not the repository-root Euler build command. Leave QUIRQ_BASE_PATH, QUIRQ_DIST_DIR, INNERNET_BASE_PATH, INNERNET_DIST_DIR, INSTANTS_BASE_PATH, and INSTANTS_DIST_DIR unset: standalone deployments use / and their normal build output. Clear stale framework/output overrides when reusing an old Vercel project.

Keep Enable access to System Environment Variables turned on in the Vercel project's Environment Variables settings. Innernet and Instants use Vercel's VERCEL variable to select their hosted behavior. See Vercel system environment variables.

  • Quitter: deploys its in-memory demonstration UI. It has no production collaboration backend.
  • Innernet: Vercel selects public demo mode and uses the committed data/demo/index.json. It does not index your computer. No database is needed for the bundled demo; optional Neon configuration is described in the Innernet README.
  • Instants: on Vercel, the existing adapter keeps the session journal in browser storage. It is a device-local prototype, not shared team persistence. See the Instants README.

After deployment, open the app, inspect browser/network errors, and refresh a nested route. For Instants, make a sample change and refresh to confirm browser persistence. Hosting instructions are provided here; this repository does not provision your Vercel projects or credentials.

Reference: Vercel monorepos and build configuration.

Netlify and Cloudflare Pages

Quitter is a static Vite app, so it can also be published independently:

SettingNetlifyCloudflare Pages
Repositoryquirq-ai/eulerquirq-ai/euler
Production branchmainmain
Base / root directoryapp/quitterapp/quitter
Build commandnpm run buildnpm run build
Publish / output directorydistdist
Build Node versionNODE_VERSION=24NODE_VERSION=24

Set Netlify's Base directory explicitly to app/quitter, so dependencies are installed there; it is not enough to select only its Package directory. The publish directory is relative to that base. Keep QUIRQ_BASE_PATH and QUIRQ_DIST_DIR unset. These deployments do not include Euler's Node server, dock, or the two Next.js apps.

Reference: Netlify monorepo settings and Cloudflare Pages build settings.

Public hosting limits

Euler currently binds to 127.0.0.1, accepts loopback Host/Origin values, and stores enabled settings and app data on local disk. It has no user-account or multi-tenant authentication layer. Setting a provider's PORT variable alone does not configure this host; use its explicit --port option for private deployments.

A full public deployment on Vercel, Render, Railway, Fly.io, or another container/function platform needs an intentional adapter: public-address and origin handling, authentication, durable app storage, and a deployment lifecycle suitable for the host's in-process Next runtimes. This repository does not yet supply that adapter or a ready-to-deploy container image. Use the private VM recipe for complete Euler today.

Development

The repository owns its manifest and app sources:

text
euler/
├── bin/euler.mjs # executable
├── euler.workspace.json # apps and build commands
├── nx.json # task orchestration
├── src/ # HTTP host, builds, settings, app lifecycle
├── app/
│ ├── home/ # all Euler UI; Home served at /
│ │ ├── public/ # Home, dock, avatar, icons, Blobatar
│ │ ├── src/ # dock document integration
│ │ ├── server.mjs # Home assets, routes, document hooks
│ │ └── tests/ # Home and shared UI tests
│ ├── innernet/ # Next.js
│ ├── quitter/ # Vite + React
│ └── instants/ # Next.js
└── tests/ # host regression tests
CommandPurpose
npx nx show projectsList the host, Home, and three bundled app projects.
npx nx run euler-app:startStart Euler.
npx nx run euler-app:buildValidate Home and build enabled apps.
npx nx run euler-home:devStart Home through the Euler host at port 2713.
npx nx run euler-home:buildValidate Home's browser-ready source files.
npx nx run euler-home:testRun the focused Home tests.
npx nx run euler-innernet:buildBuild Innernet for its Euler route.
npx nx run euler-quitter:devStart standalone Quitter development.
npm run setup -- homeConfirm Home needs no dependency installation.
npm run build -- --app homeValidate Home without building the other apps.
npm run build -- --app instantsBuild one app even if disabled; leave its enabled setting unchanged.
npm testRun the host and Home test suites.

You can also cd app/quitter and run npm run dev, or use the other apps' own commands. Standalone development uses the app's original port and root path. Euler builds go into .next-euler or dist-euler to keep development output separate. Stop Euler before rebuilding a build it is serving.

Home is a first-class local app in app/home. From that folder, npm run dev or npm start launches the same Euler host, API, and enabled apps at http://localhost:2713/. Stop an existing Euler process before starting another on that port. npm run build validates Home's HTML, CSS, and JavaScript, and npm test runs its focused tests. Home uses browser-ready source with no app dependencies or generated bundle; Nx also exposes its start and setup targets.

Home stays available as Euler's control surface, so it has no enable switch or upstream repository to synchronize. Euler's built-in UI belongs to app/home, including the dock, avatar renderer, icons, vendored Blobatar, and the integration that adds the dock to app pages. The repository root handles hosting, security, builds, configuration, and app lifecycle. Hosting Home requires the full Euler host described in Deployment.

To adapt the dock for a particular app, add an optional dock configuration to that app's manifest entry and keep its assets in the app's public/euler/ folder. A stylesheet themes the standard dock; a module exports mount(context) to render a custom interface. The app dock guide includes a copyable example and the shared navigation/state contract.

npm start resolves euler.workspace.json from this repository, regardless of your terminal's current directory. Use --workspace /path/to/euler or --config /path/to/euler.workspace.json to choose a custom installation. Nx runtime/build targets disable caching because local settings and data affect their behavior.

Already have an older checkout with sources in apps/? Stop Euler and follow the folder migration instructions to preserve local app data, then reinstall and rebuild under app/. Existing hosting projects must also update their app Root Directory or Base directory to the paths above.

Update an app from its upstream repository

App updates are manual. Innernet, Quitter, and Instants keep their own repositories; Euler tracks their sources as Git subtrees under app/. Ordinary cloning, setup, and builds are unchanged.

Commit your local Euler changes first, then run these commands from the repository root:

sh
npm run apps:check
npm run apps:sync -- innernet
npm run setup -- innernet
npm run build -- --app innernet
npm test

apps:check fetches upstream information without changing app files. apps:sync merges one app at a time and creates a local Euler commit containing its source changes and updated upstream pin. Replace innernet with quitter or instants as needed. Stop Euler before rebuilding an app it is serving.

If a merge conflicts, resolve the files, stage them with git add, then run npm run apps:sync -- --continue; use npm run apps:sync -- --abort to cancel that merge. After validation, push your Euler branch through your normal workflow. These commands do not push changes to the standalone app repositories or schedule future updates. See the app maintenance guide for the full workflow and recovery steps.

Data and settings

DataStored inLifetime
Enabled apps.workspace-state/euler/config.jsonAcross server restarts
Innernet local indexapp/innernet/data/*.jsonOn the host machine
Innernet local database~/.innernet/db by defaultOn the host machine; optional INNERNET_DB_DIR override
Innernet local history~/.innernet/history by defaultOn the host machine; optional INNERNET_HISTORY_DIR override
Instants local journalsapp/instants/session/<id>/session.jsonOn the host machine
Avatar and dock opacityBrowser local storagePer browser and origin
Last route and scrollBrowser session storagePer browser tab

Keep a persistent disk for server-hosted Euler and back up local data with the service stopped. Fresh clones contain source and bundled public demo material, not your personal index or journals. Browser preferences use separate storage when the host or port changes.

Project notes

  • This repository is quirq-ai/euler. It replaces the older Python watcher with the standalone app workspace.
  • The original iframe-based quirq dashboard remains separate on quirq-ai/quirq's feat/standalone-dashboard, at port 4400.
  • In the larger local quirq workspace, npm run euler starts apps/euler, while npm start opens the separate dashboard. This repository also works as a fresh independent clone.
  • Source provenance records imported app revisions and adapters. Architecture and the user guide explain the host in more detail.
  • Blobatar is vendored locally under its MIT license in app/home/public/vendor/blobatar. Avatar rendering and saving do not contact an external service.
  • CI runs host tests on Node 22/24 and application builds on Node 24 across Windows, macOS, and Linux.

View README.md on GitHub ↗