* Add embeddable Puter toolbar and shared app browser Provide deployment-scoped iframe routes, a responsive host helper, read-only app browsing, saved-account switching, and new-tab account and upgrade links. Validate account sessions before switching and keep credentials inside the GUI origin. Verified with 182 targeted tests, production GUI build, backend type checking, lint, and a real-backend browser smoke test. Translation checker could not run because tools/check-translations.js is missing. * Prevent embedded toolbar from scrolling when menus open * Stop double-encoding translated toolbar labels i18n() already HTML-encodes its result, so wrapping it in escape() again turned accented labels into literal entities (e.g. "Schließen") for screen readers, and .text() did the same for the error message. * Load only the preferred language in the toolbar and app browser embeds Importing i18n.js pulled every translation into each embed, making the toolbar bundle 1.1 MB. The embeds now bundle English and fetch the user's language on demand (toolbar 1.12 MB -> 179 KB, app browser 1.18 MB -> 237 KB). The desktop bundle keeps all translations. * Keep toolbar buttons in place when a menu opens near the viewport edge On phones the expanded frame was clamped to an 8px viewport margin, which moved the whole toolbar row (by the header padding minus 8px) under the user's finger. The frame now shrinks to fit beside and below the collapsed toolbar, and only falls back to shifting when there isn't enough room. * Don't pull focus back into the toolbar when the host page closes its menu Clicking a host text field while a toolbar menu was open closed the menu and then refocused the toolbar button, so the host field lost focus and typing went nowhere. Focus is now restored only while the toolbar document has it. * Close toolbar menus when the empty part of the expanded frame is pressed While a menu is open the toolbar frame covers host content beside the buttons; presses there reached neither the host nor the toolbar's outside click handling, so the menu stayed open. They now close it. * Omit the empty email line in the toolbar account menu Temporary accounts and saved accounts without an email rendered an empty element, adding a stray gap under the username. * Stop user-hosted sites from framing the toolbar and app browser embeds frame-ancestors allowed every *.<domain> subdomain, which on the default self-hosted layout includes user sites (*.site.<domain>) and private apps (*.app.<domain>), letting any hosted page clickjack sign-out and account switching. The policy now names the embedding page exactly, from the request's referrer, and refuses the user-content hosting domains. * Use the dashboard danger color for the toolbar sign-out confirmation The hardcoded red had 3:1 contrast on the dark panel, below WCAG AA for 14px text. The dashboard's danger token is 4.8:1 in light and 6:1 in dark. * Drop the dashboard's hamburger clearance from the embedded app browser At narrow widths the dashboard pads the search 60px down to clear its fixed menu button. The embeds have no such button, so the toolbar's app panel lost 90px of a ~500px frame to empty space above the search. * Keep the toolbar's Upgrade button legible in dark mode Upgrade was filled with the link color, which dark mode lightens to #6b8cff: 3.1:1 under white text. Use the dashboard's primary-button fill (4.6:1 in both themes) and its hover color, and drop the button classes nothing styles on this page. * Keep the toolbar's apps icon legible on hosts in the other theme The toolbar follows the OS theme but draws on the host page, so in dark mode on a light host its icon was #d4d4d4 on white (and the reverse on a dark host). Give the apps toggle a surface of its own, like the avatar beside it, and the session-unavailable notice one too. * Let the toolbar sign out of a session that already ended When the session was ended elsewhere (revoked, or signed out in another tab), the anti-CSRF and logout requests answer 401 and sign-out failed on every retry, stranding the stale token. Treat 401 as already signed out and finish clearing it locally, as the desktop does; other failures still keep the session and show the error. * Keep the toolbar's slot following the host layout while a menu is open The helper reserved the toolbar's space with a span frozen at the frame's resolved size and margins, so a host that right-aligns it with margin-left: auto (or sizes it in percentages or media queries) left the open menu anchored to a stale spot, overflowing the header, after a resize or rotation. Reserve it with an empty clone of the frame instead, which the page's own rules keep laying out; if they target data-puter-toolbar, which the clone drops so hosts still find one frame, hold the frame's measured size. * Reuse isOrgSeat for the toolbar's Upgrade check The toolbar re-implemented the dashboard's organization-seat test inline. Use the shared helper so both surfaces agree on who sees an upgrade offer. * Point comments at AppBrowser.js, where the Apps tab code now lives The constants and methods these comments name moved out of TabApps.js when the app browser became shared. * Restore the license header on the new embed and toolbar files TabApps.js lost its AGPL header when its code moved to AppBrowser.js, and the new embed, toolbar, and host-helper modules were added without one; every other GUI source file carries it. * Remove the embeddable toolbar, keeping the standalone app browser Drop /embed/toolbar, its page and host helper, their styles, strings and tests, and the dashboard's ?upgrade=1 deep link that only the toolbar's Upgrade button used. /embed/apps no longer allows the GUI origin to frame it with a wildcard over deployment subdomains, which existed only for the toolbar's nested app browser, and its bootstrap config no longer carries the domain the toolbar read.
The Open-Source Internet Computer!
« LIVE DEMO »
Puter.com
·
App Store
·
AI Builder
·
Developers
·
X
Puter
Puter is an advanced, open-source, self-hostable internet computer designed to be feature-rich, fast, and highly extensible.
For Users
Puter's goal is to provide you with every app and feature you need to work, create, and play under one roof. From a simple Notepad and Voice Recorder to Spreadsheet and Camera, Puter wants to be the all-in-one solution for your digital life.
For Developers
Puter provides everything you need to build and publish web apps and games. From AI to Cloud Storage and Database to Serverless Workers, Puter has you covered. Puter also helps you get users! Once you build your app, you can publish it on our App Store to reach and monetize users.
Getting Started
💻 Local Development
git clone https://github.com/HeyPuter/puter
cd puter
npm install
npm start
→ This should launch Puter at http://puter.localhost:4100
To run this checkout with Docker, follow Building from source. Create a local docker-compose.override.yml to select the local build; keeping these settings out of docker-compose.yml avoids conflicts when pulling updates and keeps local configuration out of pull requests.
🚀 Self-Hosting
Linux/macOS
curl -fsSL https://puter.com/selfhost | sh
Windows
irm https://puter.com/selfhost?os=windows | iex
→ For more details, see Self-Hosting Puter.
☁️ Puter.com
Puter is available as a hosted service at puter.com.
Support
Connect with the maintainers and community through these channels:
- Bug report or feature request? Please open an issue.
- X (Twitter): x.com/HeyPuter
- Security issues or abuse reports? security@puter.com
- Email maintainers at hi@puter.com
We are always happy to help you with any questions you may have. Don't hesitate to ask!
License
This repository, including all its contents, sub-projects, modules, and components, is licensed under AGPL-3.0 unless explicitly stated otherwise. Third-party libraries included in this repository may be subject to their own licenses.
Translations
- Arabic / العربية
- Armenian / Հայերեն
- Bengali / বাংলা
- Chinese / 中文
- Danish / Dansk
- English
- Farsi / فارسی
- Finnish / Suomi
- French / Français
- German / Deutsch
- Hebrew/ עברית
- Hindi / हिंदी
- Hungarian / Magyar
- Indonesian / Bahasa Indonesia
- Italian / Italiano
- Japanese / 日本語
- Korean / 한국어
- Malay / Bahasa Malaysia
- Malayalam / മലയാളം
- Dutch / Nederlands
- Polish / Polski
- Odia / ଓଡ଼ିଆ
- Portuguese / Português
- Punjabi / ਪੰਜਾਬੀ
- Romanian / Română
- Russian / Русский
- Spanish / Español
- Swedish / Svenska
- Tamil / தமிழ்
- Telugu / తెలుగు
- Thai / ไทย
- Turkish / Türkçe
- Ukrainian / Українська
- Urdu / اردو
- Vietnamese / Tiếng Việt

