Library / SDK
primer/octicons avatar
primer/octicons

Primer Octicons: one SVG source, six packages, and an alias system that keeps old icon names working

A scalable set of icons handcrafted with ❤️ by GitHub

8,781 stars848 forksTypeScriptMIT

At a glance

What is it?
Octicons is GitHub's own SVG icon set, built from one icons folder into JavaScript, React and Ruby packages. The interesting parts are how renamed icons stay addressable and why helpers still return 24px artwork when you ask for nothing.
Who is it for?
Octicons suits teams building GitHub-style interfaces in React, Node, Rails or Jekyll who want icons that match GitHub's own UI under an MIT code license. It is a poor fit if you need a webfont or a React Native component, since none of the six listed packages is one.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • primer/octicons8,781 ★ · +22
Star history
Repository2026-09-222026-11-14
primer/octicons8.8k8.8k

22 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

One icons folder feeds six published packages under lib/

Octicons is a set of SVG icons built by GitHub for GitHub. Each consumer library lives in its own folder under lib/ and targets a different platform. On the JavaScript side there are three npm packages: @primer/octicons, the Node.js package with a JavaScript API; @primer/octicons-react, which exposes the icons as React components; and @primer/styled-octicons, React components that accept Styled System props. On the Ruby side there are three gems: octicons, a Ruby API; octicons_helper, a Rails helper; and jekyll-octicons, a Jekyll plugin.

The Ruby packages move in lockstep. octicons_gem, octicons_helper and jekyll-octicons were all tagged 19.42.0 on 2026-10-23, within seconds of each other, and the last push to main landed on 2026-11-02. The workspace list in package.json also names lib/octicons-react-symbols, which has no row in the package tables, so treat it as internal unless its own folder says otherwise.

The build turns icons/*.svg and icon-metadata.json into data.json

Every package reads from the same generated data. The root build script takes every SVG under icons/, merges it with icon-metadata.json, and writes both a JSON data file and a folder of processed SVGs:

code
"build": "script/build.ts --input icons/**/*.svg --metadata icon-metadata.json --output lib/build/data.json --svg-output lib/build/svg",

The raw artwork is cleaned with svgo using svgo.config.mts, and a keywords.json file sits at the top level next to icon-metadata.json. The practical effect is that an icon change happens once, in icons/, and every library picks it up from lib/build. It also means the build/svg paths are part of the public surface: the compatibility rules below promise that published build/svg paths survive renames, so anything that links to those files directly is covered.

Renamed icons survive as aliasOf entries instead of disappearing

Octicons does not delete an icon name when it renames one. Three cases are spelled out. bookmark-filled is now a deprecated compatibility name for bookmark-fill. repo-deleted is a deprecated compatibility name for repo-delete. play is a supported compatibility name for triangle-circle.

A compatibility name keeps its exports, its CSS classes, its symbol IDs and its published build/svg path. In the icon data, an aliasOf property points at the canonical name, and a separate deprecated: true flag marks the aliases you should move away from. play has aliasOf but is not deprecated. If you build an icon picker or catalogue, filter out entries that carry aliasOf so each icon appears once, while existing code that looks up the old name keeps working. The shape names triangle, triangle-circle and triangle-fill follow the naming pattern of the square family.

An alias does not always draw the same thing as its canonical icon

The alias system preserves behavior, and that includes old drawings. bookmark-filled and repo-deleted keep their 16px drawing at every display size. Their canonical replacements, bookmark-fill and repo-delete, now ship both 16px and 24px artwork. So at a large size, the deprecated name and the canonical name render different artwork.

play is the sharper case. It retains both of its original circled drawings, not the bare triangle. If you swap play for triangle-circle during a cleanup, check the result on screen rather than assuming a rename. The consequence for a codebase is that a search and replace from old names to new names is a visual change, not a refactor, and needs the same review as any icon change. git-pull-request-unlisted ships 16px artwork only, so do not expect a 24px version of it.

Helpers still return 24px when you pass no width or height

Now that bookmark-fill and repo-delete carry both natural sizes, the JavaScript and Ruby helpers have to pick one when a caller says nothing. They keep the existing behavior: with width and height omitted, the output is the 24px drawing. An explicit 16px request selects the 16px drawing.

This is a compatibility choice, and it has a cost. A component that renders an icon inline in dense text without a size gets the 24px artwork scaled by CSS, not the 16px drawing designed for that size. If your interface relies on the small icons, pass the size explicitly everywhere you call the helper. Triangle, triangle-circle and triangle-fill also provide 16px and 24px artwork, so the same rule applies to them.

The root package.json is a monorepo shell that refuses to publish

Cloning the repository does not give you a library to import. The root package.json is named octicons, marked private: true, and its publishConfig registry is set to the string "no registry, don't publish from this package.json." It declares npm workspaces for examples/* and lib/*, pins packageManager to [email protected], and drives the build with turbo.

Versioning goes through Changesets, with changeset:version and changeset:publish scripts and a .changeset/ folder. Tests run on vitest 4.1.10 with the Playwright browser provider, and type checks run tsc --noEmit. There is a Next.js example in examples/octicons-react-nextjs/. A Ruby toolchain sits alongside: a Gemfile, a Rakefile and .rubocop.yml. If you only want icons in an app, install the published package for your platform; the root workspace is for working on Octicons itself.

Icon requests are gated to GitHub staff, and logos fall outside MIT

Anyone can open an issue with a bug, feedback or an idea using the repository's issue templates, and CONTRIBUTING.md has a section on adding or updating icons. Requesting an icon review for inclusion in the library is different: it is marked GitHub staff only and goes through the Icon request template in the github/primer repository. For outside teams, this means you cannot count on a missing icon being added on request; drawing your own icon in the same style is the fallback.

The license has two parts. Code is under the MIT license, which applies to all files other than the GitHub logos. The logos are under GitHub's logo guidelines. If you ship the GitHub mark from Octicons in your product, the MIT terms do not cover that use; the logo guidelines do.

Editorial conclusion

Octicons suits teams building GitHub-style interfaces in React, Node, Rails or Jekyll who want icons that match GitHub's own UI under an MIT code license. It is a poor fit if you need a webfont or a React Native component, since none of the six listed packages is one. Before adopting it, decide which size you want and pass width and height explicitly, check whether any name you use is a deprecated alias, and keep GitHub logos within GitHub's logo guidelines.

Frequently asked questions

What is the main purpose of icons?

In Octicons, icons are SVG artwork built by GitHub for GitHub's own interface, shipped to JavaScript, React and Ruby code through six packages so that every platform draws the same symbols.

What is an example of an icon?

Octicons includes bookmark-fill and repo-delete, each with 16px and 24px artwork, and triangle-circle, which can also be addressed by its supported compatibility name play.

How do icons work?

Octicons keeps SVG files in an icons folder; a build script merges them with icon-metadata.json into lib/build/data.json and lib/build/svg, which the npm packages and Ruby gems read. Helpers return the 24px drawing unless you request 16px.

Official sources

  1. License: MIT
  2. primer/octicons on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/primer-octicons.svg)](https://hysenlabs.com/projects/primer-octicons)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/primer-octicons.svg)](https://hysenlabs.com/projects/primer-octicons)

Was this useful?