Badges, banners and icon previews for the Flow projects, generated from config and served from one place: https://assets.flow-tube.org/v1/. Browse them all, with copy-ready snippets, at assets.flow-tube.org.
| Folder | What | Size |
|---|---|---|
v1/badges/pill/ |
Download and call-to-action buttons | 60px high |
v1/badges/split/ |
Info chips, the shields.io replacement | 32px high |
v1/badges/tile/ |
Project tiles for the org profile and website | 152 × 152 |
v1/banners/ |
README banners, plus social previews (-social-*.png) |
1280 × 420, 1280 × 640 |
v1/icons/ |
Launcher icon previews, SVG and 512px PNG | 108dp canvas |
v1/stars/ |
Star history charts, updated daily | 960 × 460 |
v1/manifest.json |
Index of every file: kind, id, theme, size, alt text, link |
Every badge and banner comes as <id>-light.svg and <id>-dark.svg, and some also as <id>-light-animated.svg / <id>-dark-animated.svg.
Text is outlined into paths, so the files look the same everywhere and need no fonts.
Files under v1/ never change name, never move and are never deleted. Their content can change (new numbers, small fixes), but every URL keeps working.
CI fails any change that removes or renames a v1/ path. A redesign that can't keep that promise goes into v2/, next to v1/.
Use <picture> with prefers-color-scheme, so readers with a dark theme get the dark file. GitHub supports this in READMEs.
Pill (60px):
<a href="https://github.com/Flow-Tube/Flow/releases/latest">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://assets.flow-tube.org/v1/badges/pill/get-github-dark.svg">
<img alt="Get it on GitHub" src="https://assets.flow-tube.org/v1/badges/pill/get-github-light.svg" height="60">
</picture>
</a>Info chip (32px):
<a href="https://github.com/Flow-Tube/Flow/releases/latest">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://assets.flow-tube.org/v1/badges/split/release-dark.svg">
<img alt="Release" src="https://assets.flow-tube.org/v1/badges/split/release-light.svg" height="32">
</picture>
</a>Tile (152px):
<a href="https://github.com/Flow-Tube/Flow">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://assets.flow-tube.org/v1/badges/tile/tile-android-dark.svg">
<img alt="Flow for Android" src="https://assets.flow-tube.org/v1/badges/tile/tile-android-light.svg" width="152">
</picture>
</a>Banner (full width):
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://assets.flow-tube.org/v1/banners/flow-android-dark.svg">
<img alt="Flow. Privacy-first YouTube and YouTube Music for Android." src="https://assets.flow-tube.org/v1/banners/flow-android-light.svg" width="100%">
</picture>Star history chart (full width, links to the stargazers):
<a href="https://github.com/Flow-Tube/Flow/stargazers">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://assets.flow-tube.org/v1/stars/stars-flow-android-dark.svg">
<img alt="Star history of Flow for Android" src="https://assets.flow-tube.org/v1/stars/stars-flow-android-light.svg" width="100%">
</picture>
</a>Icon preview (no light/dark versions):
<img alt="Flow launcher icon: Scallop" src="https://assets.flow-tube.org/v1/icons/expressive_scallop-512.png" width="96" height="96">The animated files rotate the shape slowly and stand still for readers who turn on reduced motion. Use them for one hero badge at most.
const ASSETS = "https://assets.flow-tube.org/v1";
// kind: "pill" | "split" | "tile"; height in px (60, 32 or 152)
export function FlowBadge({ kind = "pill", id, alt, href, height = 60, theme }) {
const file = (t) => `${ASSETS}/badges/${kind}/${id}-${t}.svg`;
// With a site theme toggle, pass theme="light" | "dark"; otherwise follow the OS.
const img = theme ? (
<img src={file(theme)} alt={alt} height={height} />
) : (
<picture>
<source media="(prefers-color-scheme: dark)" srcSet={file("dark")} />
<img src={file("light")} alt={alt} height={height} />
</picture>
);
return href ? <a href={href}>{img}</a> : img;
}
// <FlowBadge id="get-github" alt="Get it on GitHub" href="https://github.com/Flow-Tube/Flow/releases/latest" />v1/manifest.json lists every file with its alt text and href, if you'd rather build the list from data.
If assets.flow-tube.org is ever unreachable, the same files are on jsDelivr, pinned to a tag:
https://cdn.jsdelivr.net/gh/Flow-Tube/Brand@v1.0.0/v1/badges/pill/get-github-light.svg
A tag is a snapshot, so the live numbers on the release and download chips stay at the tagged values.
READMEs should use assets.flow-tube.org; keep jsDelivr for the website's fallback.
- Edit
tools/badges.json(orbanners.json,palette.json). Icons aresi:<name>from Simple Icons,ms:<name>from Material Symbols (Rounded, filled), orflowfor the Flow mark.categorypicks the shape:download,nightly,community,info,support,project,brand. - Open a PR. The
buildworkflow renders everything, runstools/check_assets.pyand uploadsv1/as an artifact. - Download the artifact from the PR's checks and review the files.
- Merge. CI commits the regenerated
v1/tomain(chore(assets): regenerate) and the site redeploys.
Never edit files in v1/ by hand; CI would overwrite them. See CONTRIBUTING.md.
python3 -m venv .venv && . .venv/bin/activate
sh tools/setup.sh # pinned npm + pip deps, builds tools/fonts/gsf.ttf
python3 tools/flowbadges.py
python3 tools/flowbanners.py
python3 tools/flowicons.py --previews-only
python3 tools/make_manifest.py
python3 tools/check_assets.py --base origin/mainDependencies are pinned in tools/package-lock.json and tools/requirements.txt, so CI renders the same bytes as your machine.
PNGs are rendered with resvg, which needs no browser.
The release and downloads chips (Flow for Android) and desktop-release and desktop-downloads (Flow Desktop) are refreshed by the stats workflow:
- every day at 03:17 UTC, on demand, and when a
flow-releaseevent arrives (below) - release = the newest stable tag, ignoring prereleases and drafts
- downloads = every asset of every release, rounded down so it never overstates:
950,9.1k+,48k+,1.2M+ - the values are saved to
tools/badges.jsonand only those chips are re-rendered; it commits only when an SVG changed
The same stats run rebuilds the charts in v1/stars/ with tools/flowstars.py:
- Data comes from GitHub's
/repos/{owner}/{repo}/stargazers/historyendpoint: stars per day, no usernames, a page or two per repo. The built-in Actions token is enough. tools/data/stars-state.jsonkeeps the last rendered totals. A chart whose totals haven't changed is skipped, so the "Updated" date doesn't create a commit every day. Run with--forceto re-render anyway.- To add a chart, add an entry to
chartsintools/stars.jsonwith anid(the file name),href,title,subtitle,unitand one or morerepos. To add a repo to a chart, add{"repo": "owner/name", "label": "...", "color": n}to itsrepos. colorpicks the series colour:0is Flow red and1is Desktop blue. Give a project the samecolorin every chart, so it reads the same everywhere.- Charts with one repo get milestone markers and a filled area; charts with several get a legend and labels at the line ends.
- Preview without touching the API:
python3 tools/flowstars.py --sample --out /tmp/stars. Sample charts say "Sample data" andcheck_assets.pyrefuses them inv1/.
Add this step to the end of the release workflow in Flow-Tube/Flow:
- name: Refresh the brand release chips
env:
GH_TOKEN: ${{ secrets.BRAND_DISPATCH_TOKEN }}
run: gh api repos/Flow-Tube/Brand/dispatches -f event_type=flow-releaseBRAND_DISPATCH_TOKEN is a fine-grained personal access token:
- GitHub → Settings → Developer settings → Fine-grained tokens → Generate new token.
- Resource owner: Flow-Tube. Repository access: Only select repositories →
Flow-Tube/Brand. - Repository permissions: Contents: Read and write (needed to send
repository_dispatch). Metadata: Read-only is added automatically. - In
Flow-Tube/Flow→ Settings → Secrets and variables → Actions, add it asBRAND_DISPATCH_TOKEN.
The Flow-Tube org must allow fine-grained tokens (org Settings → Personal access tokens). The same step works from Flow-Tube/Flow-Desktop.
- Code in
tools/andsite/: GPL-3.0, same as Flow. - Generated artwork in
v1/: CC BY-SA 4.0. - Google Sans Flex, the typeface outlined into the artwork: SIL OFL 1.1.
- GitHub, Reddit, Patreon, Weblate, Apple, Linux, Android and Obtainium names and logos are trademarks of their respective owners. Their use here identifies where to get Flow or how to reach the community and does not imply endorsement.
- The third-party logos come from Simple Icons, released under CC0 1.0. (The Patreon badge uses a Material Symbols heart, not the Patreon logo.)
- Material Symbols are © Google, licensed under the Apache License 2.0.
- The Flow name and logo identify the Flow project. CC BY-SA 4.0 covers the artwork's copyright only, not trademark rights.