wayBetter

(FOSS) One system for every app

The apps you use, way better.

wayBetter puts the apps you already use in a light native window and extends them in place, the way BetterDiscord extends Discord. Tabs, split panes, every account side by side, themes, plugins and fixes for the app's own bugs. Anyone can make a theme or a plugin. Anyone can build the next app.

Get wayBetter for X

Download wayBetter for X for Windows · free · GPL-3.0-or-later · no telemetry on what you read or post

  • 14 themes in wayBetter for X
  • 10 bundled plugins
  • 9 fixes for X's own bugs
  • 0 dependencies in waybetter
  • $0 forever

01 The problem

Every app ships half of what you need.

The rest you can't have: the app decides how many accounts you get, how it looks, and when its bugs get fixed. wayBetter keeps the app and adds the other half.

  1. A

    One account per window. Log out, log in, repeat.

    Every account, side by side, all signed in at once.

  2. B

    A bug in the app? Wait for them to fix it.

    Fixed on your machine, in place, today.

  3. C

    The look they picked. The features they shipped.

    Themes and plugins anyone can write.

  4. D

    A whole browser bundled into every desktop client.

    One light native window, on the system WebView.

02 One system

Three layers around the real app.

Every wayBetter app is the same system: a native Shell, a page Runtime, and one small Adapter that knows the app. The app itself keeps doing what it does. Nothing is proxied or re-hosted; it changes on your machine only.

01 · Shell

A light native window.

Tauri 2, on the system WebView. The chrome you wish every app had:

  • Tabs, pinned tabs and split panes: drag a tab or a link to an edge
  • Every account in its own profile, signed in side by side
  • Link routing: open in the same tab, beside, in a new tab or your browser
  • Address bar and command palette Ctrl K
  • Signed updates that install silently

02 · Runtime

Themes and plugins, inside the page.

Injected into the app's own pages, shared by every wayBetter app:

  • Themes on one color foundation (an OKLab model of the app's palette)
  • BetterDiscord-style JavaScript plugins with a small helper API
  • One DOM hub and one request hub, so features stay cheap
  • Your own CSS, applied after the theme

03 · Adapter

One small piece per app.

The only part that knows the app: its hosts, its layout, its account button and the data it already loads.

  • A native SiteSpec and a page SiteAdapter
  • A short, reviewed list of what the app's tabs may call
  • Everything else comes from the system

03 The first app

wayBetter for X.

The live x.com in tabs and split panes, every account side by side, fourteen themes, ten plugins and fixes for the bugs X ships: likes and follows that race, drafts that vanish, a timeline that jumps. Available now for Windows; macOS and Linux later.

14built-in themes, and yours
10bundled plugins, off until you turn them on
9fixes for X's own bugs
36tweaks to hide, show and change X
  • 01
    Every account, side by side

    Tabs and split panes on the live x.com, each account signed in at once in its own profile.

  • 02
    X's bugs, fixed

    Likes and follows that land, your place kept on Back, no timeline jumps, retried uploads.

  • 03
    A draft vault

    Every draft kept locally with its revision history, and put back when X loses it.

  • 04
    Fourteen themes, ten plugins

    Full redesigns, not just colors. Plugins like Thread Reader, Muted Regex and User Notes.

  • 05
    Ctrl+K for everything

    A command palette for tabs, accounts, settings and X search with operator chips.

wayBetter for X

Free · open source · updates silently

Download for Windows See everything

Windows now · macOS and Linux later

04 Make it yours

Anyone can make themes and plugins.

A theme is one JSON file. A plugin is one JavaScript file. No store, no review queue, no account: write it, drop it in, share the file. If you can write CSS, you can restyle an app. If you can write a little JavaScript, you can add the feature it never shipped.

Themes

Colors, fonts, shape, layout, background, effects.

Import and export JSON in the Appearance panel. Contrast is checked for you: text is kept readable on every surface.

HomePost
For youFollowing
wayBetter@CRTkafa · 2m

Fourteen themes ship with it. The fifteenth is yours.

1248♥ 101
playfishies@playfishies · 9m

One JSON file. Drop it into Appearance → Import.

Night Ink
deep-sea.theme.json
{
  "name": "Deep Sea",
  "author": "@you",
  "mode": "dark",
  "colors": { "bg": "#06141b", "text": "#e6f4f1", "accent": "#2ee6c5" },
  "font": { "family": ["Geist"], "scale": 1.02 },
  "shape": { "radius": 14, "button": 9999, "avatar": "rounded" },
  "layout": { "density": "compact", "cards": true },
  "background": { "kind": "pattern", "pattern": "grid",
                  "ink": "#2ee6c5", "opacity": 0.08, "size": 28 },
  "effects": { "hover": "glow" }
}
Plugins

One file. start() and stop().

BetterDiscord-style *.plugin.js, dropped into the plugins folder and switched on in Settings. A helper API does the fiddly parts.

copy-quote.plugin.js
/**
 * @name Copy Quote
 * @description y on a focused post copies "@handle: text".
 * @version 1.0.0
 * @author @you
 */
module.exports = class CopyQuote {
  start() {
    const api = window.BetterTwttr.api;
    this.scope = api.scope();
    this.scope.onKey((event, post) => {
      if (event.key !== 'y' || !post) return;
      const t = api.tweet(post);
      if (t) api.copyText(`@${t.handle}: ${t.text}`)
        .then(() => api.toast('Copied'));
    });
  }
  stop() { this.scope.dispose(); }
};

Helper API

  • storage(ns)
  • observe(sel, fn)
  • onRouteChange(fn)
  • onKey(fn)
  • tweet(el)
  • copyText(s)
  • toast(msg)
  • injectCSS(id, css)
  • waitFor(sel)
  • scope()

Ten ship with wayBetter for X

  • Thread Reader
  • Exact Timestamps
  • Clean Links
  • Copy as Markdown
  • Alt-text Reminder
  • User Notes
  • Muted Regex
  • Reading Time
  • Media Grid Focus
  • Keyboard Plus

05 Build on it

The whole system is one package.

The page runtime and the shell models behind wayBetter for X are on npm as waybetter: plain ESM with types, every module its own subpath, zero dependencies. Take the pieces you need, or build a whole app.

terminal

npm i waybetter

zero dependenciesESM + .d.tsruntime/* and shell/*GPL-3.0-or-later
adapter.ts · from the README, shortened
import { configureRuntime, type SiteAdapter }
  from 'waybetter/runtime/site';

export const KICK: SiteAdapter = {
  product: 'wayBetter for Kick',
  hosts: ['kick.com'],
  runtimeGlobal: 'WayBetterKick',
  apiMarks: ['/api/'],
  // plugins, rail, account, links, themeSources …
};
configureRuntime(KICK);

waybetter/runtime/*

  • sitethe adapter's composition root
  • domHubone MutationObserver, one frame
  • netHubone fetch/XHR hook for every feature
  • pluginApihelpers for user plugins
  • themeTokensthe OKLab color model
  • paneNavone navigation in split view
  • linkRoutingbeside, tab or browser
  • accountReportwhich account is signed in

waybetter/shell/*

  • addressModeladdress bar chips
  • paneModelsplit panes, links beside
  • linkDropdrop a link, get a pane
  • palettecommand palette ranking
  • profileModelaccount profiles
  • updateModelthe update chip
  • windowControlstitlebar and caption buttons
  • chrometitlebar and toolbar sizes

06 What's next

X was first. You build the next one.

Any app with a web version can get the same window, themes and plugins. These could be next. None of them is announced, and none has a date: they are waiting for someone to write the adapter. The README's own adapter example is Kick.

possible

wayBetter forYouTube?

Tabs and split panes for videos, every channel account side by side, themes, plugins.

possible

wayBetter forKick?

Streams side by side in one light window, your chat plugins, your theme.

possible

wayBetter forTwitch?

Multi-stream split panes, every account signed in, plugins for chat.

possible

wayBetter forDiscord?

The web app in a light Tauri window instead of the heavy client. Same shell, same plugins.

wayBetter forthe app you use.

Write the adapter. The shell, runtime, themes and plugins come with it.

npm i waybetter

Build the next one.

Start from the package and the README's adapter example. Built something? Add it to the "Projects using wayBetter" list with a pull request.

Start building

Possible next apps, not announced products. YouTube, Kick, Twitch and Discord are trademarks of their respective owners; their logos are shown only to name the services. wayBetter is not affiliated with, endorsed by or sponsored by any of them.

07 Free and open source

No catch. Read every line.

  1. i.

    Free

    No paid tier, no ads, no upsell. Not now, not "after the beta".

  2. ii.

    Open

    GPL-3.0-or-later. The framework and the apps are public source on git.crt.fyi.

  3. iii.

    Private

    No analytics, no telemetry on what you read or post. Drafts, settings and plugins stay on your machine.

  4. iv.

    Yours

    Fork it, theme it, write plugins, build the next app. The license keeps it open for the next person too.

08 Principles

Better, not different.

The real app, in place

You sign in to the app itself. Nothing is proxied or re-hosted; it is changed on your machine only.

Light, not another browser

A Tauri window on the system WebView, one per app, with every account inside it.

Never acts for you

Fixes make your own clicks land. wayBetter never posts, follows or deletes anything by itself.

Quietly current

Updates are signed and install silently, so fixes land without another installer.

Start with X.
Build what's next.

See wayBetter for X