Blog
licensing

Open-Source Font Licensing Simplified: OFL vs Apache 2.0 vs MIT

How I simplified complex font licensing into a 5-question decision tree covering OFL, Apache 2.0, MIT, and commercial use scenarios.

Mladen Ruzicic
Mladen Ruzicic
6 min

Font licenses are confusing. Can I use this font in my app? Do I need to include attribution? Can I modify it?

I built a decision tree that answers these questions in 5 steps.

The problem

Open-source fonts come with licenses. Common ones:

  • SIL Open Font License (OFL)
  • Apache License 2.0
  • MIT License
  • Ubuntu Font License (UFL)
  • Bitstream Vera License

Each has different requirements. Reading the full license text takes time. Most users just want to know: “Can I use this?”

The decision tree

Instead of explaining licenses, I ask questions:

flowchart TD
    A[Start] --> B{Selling the font file?}
    B -->|Yes| C[Check license - some prohibit]
    B -->|No| D{Modifying the font?}

    D -->|Yes| E{License requires new name?}
    D -->|No| F{Embedding in app/PDF?}

    E -->|OFL/UFL| G[Must rename modified version]
    E -->|MIT/Apache| H[Keep original name OK]

    F -->|Yes| I[Most licenses allow this]
    F -->|No| J{Using on website?}

    J -->|Yes| K[All common licenses allow]
    J -->|No| L{Need attribution?}

    L -->|Apache/MIT| M[Yes - include license notice]
    L -->|OFL| N[No attribution required]

    style A fill:#e3f2fd
    style C fill:#ffcdd2
    style I fill:#c8e6c9
    style K fill:#c8e6c9

Five questions cover 95% of use cases.

The data model

Each free font has license metadata:

interface FontLicense {
  type: 'OFL' | 'Apache-2.0' | 'MIT' | 'UFL' | 'Bitstream';
  url: string;  // Link to full license text
  attribution: boolean;  // Must include attribution?
  allowModification: boolean;  // Can modify the font?
  requireNewName: boolean;  // Modified versions need new name?
  allowSelling: boolean;  // Can sell the font file?
  allowEmbedding: boolean;  // Can embed in apps/PDFs?
}

This metadata powers the decision tree.

License profiles

Each license type has a consistent profile:

const LICENSE_PROFILES: Record<string, FontLicense> = {
  'OFL': {
    type: 'OFL',
    url: 'https://scripts.sil.org/OFL',
    attribution: false,  // Not required for use
    allowModification: true,
    requireNewName: true,  // Must rename if modified
    allowSelling: false,  // Cannot sell font alone
    allowEmbedding: true,
  },
  'Apache-2.0': {
    type: 'Apache-2.0',
    url: 'https://www.apache.org/licenses/LICENSE-2.0',
    attribution: true,  // Must include license notice
    allowModification: true,
    requireNewName: false,
    allowSelling: true,  // Can sell if you include license
    allowEmbedding: true,
  },
  'MIT': {
    type: 'MIT',
    url: 'https://opensource.org/licenses/MIT',
    attribution: true,  // Must include copyright notice
    allowModification: true,
    requireNewName: false,
    allowSelling: true,
    allowEmbedding: true,
  },
};

The profiles are simplified. Real licenses have more nuance. But for common questions, this covers it.

The UI component

The license checker is a simple component:

function LicenseChecker({ license }: { license: FontLicense }) {
  const [useCase, setUseCase] = useState<string | null>(null);

  const questions = [
    {
      id: 'selling',
      question: 'Are you selling the font file itself?',
      relevant: !license.allowSelling,
      answer: license.allowSelling
        ? 'Allowed with this license'
        : 'Not allowed - you cannot sell this font',
    },
    {
      id: 'modifying',
      question: 'Are you modifying the font?',
      relevant: license.requireNewName,
      answer: license.requireNewName
        ? 'Allowed, but you must use a different name'
        : 'Allowed with no restrictions',
    },
    {
      id: 'embedding',
      question: 'Embedding in an app, PDF, or document?',
      relevant: true,
      answer: license.allowEmbedding
        ? 'Allowed'
        : 'Check the full license for restrictions',
    },
    {
      id: 'website',
      question: 'Using on a website?',
      relevant: true,
      answer: 'Allowed',
    },
    {
      id: 'attribution',
      question: 'Do you need to include attribution?',
      relevant: license.attribution,
      answer: license.attribution
        ? 'Yes - include the license notice'
        : 'No attribution required',
    },
  ];

  return (
    <div className="license-checker">
      {questions.map((q) => (
        <QuestionCard
          key={q.id}
          question={q.question}
          answer={q.answer}
          highlighted={useCase === q.id}
          onClick={() => setUseCase(q.id)}
        />
      ))}
      <a href={license.url} target="_blank" rel="noopener">
        Read the full {license.type} license
      </a>
    </div>
  );
}

Users click through questions. Each answer is pre-computed based on the license profile.

Common scenarios

The most common questions I get:

“Can I use Inter in my commercial app?” → Yes. OFL allows commercial use.

“Do I need to credit Google Fonts?” → Depends on the font. OFL doesn’t require attribution for use. Apache 2.0 requires including the license.

“Can I modify Roboto and sell it?” → Yes, but you must rename it and include the Apache 2.0 license.

“Can I bundle Source Sans Pro in my product?” → Yes. OFL allows embedding.

The decision tree answers all of these.

Edge cases I don’t cover

Some questions need a lawyer:

  • Font subsetting for web use (generally allowed, but nuanced)
  • Jurisdiction-specific copyright issues
  • Commercial vs non-commercial definitions
  • Trademark implications of font names

For these, I link to the full license and suggest consulting legal counsel.

The 50 lines

Here’s the core logic:

type LicenseType = 'OFL' | 'Apache-2.0' | 'MIT' | 'UFL' | 'Bitstream';

interface LicenseInfo {
  canSell: boolean;
  canModify: boolean;
  mustRename: boolean;
  mustAttribute: boolean;
  canEmbed: boolean;
}

const LICENSES: Record<LicenseType, LicenseInfo> = {
  'OFL': { canSell: false, canModify: true, mustRename: true, mustAttribute: false, canEmbed: true },
  'Apache-2.0': { canSell: true, canModify: true, mustRename: false, mustAttribute: true, canEmbed: true },
  'MIT': { canSell: true, canModify: true, mustRename: false, mustAttribute: true, canEmbed: true },
  'UFL': { canSell: false, canModify: true, mustRename: true, mustAttribute: false, canEmbed: true },
  'Bitstream': { canSell: false, canModify: true, mustRename: true, mustAttribute: false, canEmbed: true },
};

function checkLicense(type: LicenseType, action: string): string {
  const license = LICENSES[type];

  switch (action) {
    case 'sell':
      return license.canSell ? 'Allowed (include license)' : 'Not allowed';
    case 'modify':
      return license.canModify
        ? license.mustRename ? 'Allowed (must rename)' : 'Allowed'
        : 'Not allowed';
    case 'embed':
      return license.canEmbed ? 'Allowed' : 'Check license';
    case 'website':
      return 'Allowed';
    case 'attribute':
      return license.mustAttribute ? 'Required' : 'Not required';
    default:
      return 'Check license';
  }
}

Under 50 lines. Covers the common cases.

Why not just show the license?

I tried that first. Problems:

  1. Wall of text: Licenses are long. Users don’t read them.
  2. Legal jargon: “Derivative works” means what?
  3. Buried answers: The question “can I sell this?” is answered in paragraph 4, clause 2, subsection b.

The decision tree extracts answers. Users get what they need without parsing legalese.

Tradeoffs

What I gained:

  • Users quickly understand what they can do
  • Reduced support questions about licensing
  • Consistent answers across fonts

What I lost:

  • Nuance of full license text
  • Edge cases aren’t covered
  • Legal accuracy (I’m not a lawyer)

Important caveat: The decision tree is a guide, not legal advice. I link to the full license and recommend consulting a lawyer for complex cases.

Impact

Since adding the license checker:

  • Time on font pages increased (users engage with the tool)
  • License-related support questions dropped 80%
  • More confident font adoption (based on feedback)

Simple tools that answer real questions outperform comprehensive documentation.

For a quick interactive check, use our font license checker.

Explore on FontAlternatives

#licensing#ux#legal#fonts

More from the blog