devto 2026-06-25 원문 보기 ↗
Web typography should be fast to implement, compliant by design, and invisible when it works right.
Typography should be one of the simplest parts of a project.
In reality, it often ends up scattered across multiple layers:
$font-family-base variablesThe same font information gets copied and maintained in several places. Every update means touching multiple files, hoping everything stays in sync.
It's repetitive, error-prone, and easy to get wrong.
So I built Font Manager.
Define your fonts once and export them in whatever format your project needs — CSS, Bootstrap variables, Tailwind configuration, TypeScript definitions, design tokens, and more.
A simple Twig function:
{{ font_manager('Ubuntu', '400 700') }}
Configuration:
symfinity_font_manager:
export:
formats:
- scss_bootstrap
- tailwind_config
- typescript_definitions
One lock command:
php bin/console fonts:lock
Every format, automatically generated. Perfectly synced.
Before:
// Manually copy font name
$font-family-base: 'Ubuntu', sans-serif; // ❌ Duplication
@import 'bootstrap/scss/bootstrap';
After:
symfinity_font_manager:
export:
formats: [scss_bootstrap]
php bin/console fonts:lock
// app.scss
@import './assets/styles/fonts-bootstrap'; // ← Auto-generated
@import 'bootstrap/scss/bootstrap';
Bootstrap uses your fonts automatically. No manual mapping. No duplication.
symfinity_font_manager:
export:
formats: [tailwind_config]
// tailwind.config.js
const fonts = require('./assets/fonts-tailwind.config.js'); // ← Auto-generated
module.exports = {
theme: { extend: { fontFamily: fonts.fontFamily } }
};
<p class="font-sans">Your custom font, via Tailwind.</p>
symfinity_font_manager:
export:
formats: [typescript_definitions]
import { fonts, type FontFamily } from './assets/fonts';
applyFont(element, 'sans'); // ✓ Valid
applyFont(element, 'invalid'); // ✗ TypeScript error!
Typos caught at compile time.
CSS, SCSS, JavaScript, Design Tokens — pick what you need:
php bin/console fonts:formats
CSS: Variables, Modules, @layer
SCSS: Variables, Bootstrap, Mixins
JavaScript: ESM, Tailwind, TypeScript
Design System: JSON, W3C Tokens, Figma, Style Dictionary
AssetMapper, Webpack, or Vite? Auto-detected.
Output paths adjust automatically. No config needed.
Export to Figma Tokens, Style Dictionary, or W3C Design Tokens:
formats:
- design_tokens
- figma_tokens
npx style-dictionary build # CSS, iOS, Android from one source
Design once. Ship everywhere.
Not just Google — choose your provider:
symfinity_font_manager:
default_provider: 'bunny' # GDPR-compliant, zero tracking
Google, Bunny, Fontsource, or Local. Same API. Your choice.
Architecture: Strategy pattern. Each format is a separate exporter.
Dependency resolution: Automatic. css_modules needs css_variables? Handled.
Build detection: Scans for webpack.config.js, vite.config.js, asset_mapper.yaml.
Output paths: Adjusted per build tool. AssetMapper → assets/styles/. Webpack → assets/.
php bin/console fonts:formats # List all formats
php bin/console fonts:format:info scss # Usage instructions
php bin/console fonts:export # Export manually
One command:
php bin/console fonts:migrate-from-google-fonts
Config, templates, manifest — all updated automatically.
Go to github.com/symfinity/recipes and follow the instructions to add the required recipe repository.
composer require symfinity/font-manager
That’s it. Symfony Flex does the rest.
{{ font_manager('Ubuntu', '400 700') }}
Dev: CDN
Prod: Self-hosted (after fonts:lock)
Add exports:
symfinity_font_manager:
export:
formats: [scss_bootstrap, tailwind_config]
Lock:
php bin/console fonts:lock
Use:
@import './fonts-bootstrap';
@import 'bootstrap/scss/bootstrap';
Done.
Typography shouldn’t waste your time or violate privacy law.
With font-manager, you can design freely in development, ship safely in production, and forget about fonts altogether.
One Twig function. Multiple providers. Twelve export formats. Zero manual mapping.
That’s Font Manager.
Try it now: symfinity/font-manager
If you find it useful, star the repository and share it with your Symfony community.