No install — just a URL. Works with curl, HTML, React, Next.js, Vue, Svelte, Python.
# curl — SVG
curl "https://hylab.vercel.app/api/icons/home?color=7c9a82&size=32"
# curl — PNG
curl "https://hylab.vercel.app/api/icons/home?color=7c9a82&size=64&format=png"
# curl — filter by family + category
curl "https://hylab.vercel.app/api/icons?set=tabler&category=navigation&limit=20"<!-- HTML — drop in anywhere -->
<img src="https://hylab.vercel.app/api/icons/home?color=7c9a82&size=32" alt="Home" />
<img src="https://hylab.vercel.app/api/icons/heart?color=ef4444&size=24" alt="Heart" />// React — zero deps
const Icon = ({ name, color = "7c9a82", size = 24 }: { name: string; color?: string; size?: number }) => (
<img src={`https://hylab.vercel.app/api/icons/${name}?color=${color}&size=${size}`} alt={name} />
);|
One endpoint serves 10 families. No need to install 10 packages. |
|
|
Vector for web, raster for email. |
Free, open source, CORS |
|
|
|
GET /api/icons/:name
| Parameter | Type | Default | Description |
|---|---|---|---|
name |
path | — | Icon name — home, search, heart |
color |
query | currentColor |
Hex without # — 7c9a82 |
size |
query | 24 |
Pixels 1–512 |
stroke |
query | 2 |
Stroke 0.5–4 |
fill |
query | false |
true to fill shape |
format |
query | svg |
svg · png · webp |
curl "https://hylab.vercel.app/api/icons/home?color=7c9a82&size=32"
curl "https://hylab.vercel.app/api/icons/home?format=png&size=64"
curl "https://hylab.vercel.app/api/icons/home?color=7c9a82&size=48&stroke=3&format=webp"GET /api/icons?page=1&limit=20&category=navigation&set=tabler
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
query | 1 |
Page number |
limit |
query | 50 |
Items per page — max 100 |
category |
query | — | navigation, action, media… (14 total) |
set |
query | — | Family — tabler, lucide, phosphor… (alias source) |
GET /api/icons/search?q=arrow
GET /api/icons/categories
GET /api/icons/categories?set=tabler
Filter counts to a family.
GET /api/icons/sets
GET /api/icons/sets?category=navigation
Filter families to a category.
GET /api/status
Live probes to 5 endpoints — avgResponseTime, services[], uptime.
HTML — copy & paste
<img src="https://hylab.vercel.app/api/icons/home?color=7c9a82&size=32" alt="Home" />
<img src="https://hylab.vercel.app/api/icons/search?color=ffffff&size=24" alt="Search" />
<img src="https://hylab.vercel.app/api/icons/heart?color=ef4444&size=48&format=png" alt="Heart" />
<!-- Family filter -->
<img src="https://hylab.vercel.app/api/icons/home?color=7c9a82&size=32" alt="Home" />
React — zero deps
function Icon({ name, color = "7c9a82", size = 24 }: { name: string; color?: string; size?: number }) {
return <img src={`https://hylab.vercel.app/api/icons/${name}?color=${color}&size=${size}`} alt={name} />;
}
// Family filtered list
function TablerIcons() {
const [icons, setIcons] = useState([]);
useEffect(() => {
fetch('/api/icons?set=tabler&limit=20').then(r => r.json()).then(d => setIcons(d.data));
}, []);
return icons.map(i => <Icon key={i.name} name={i.name} />);
}
Next.js — edge proxy
// app/icon/[name]/route.ts
import { NextResponse } from "next/server";
export async function GET(req: Request, { params }: { params: { name: string } }) {
const { searchParams } = new URL(req.url);
const color = searchParams.get("color") || "7c9a82";
const set = searchParams.get("set") || "tabler";
const res = await fetch(`https://hylab.vercel.app/api/icons/${params.name}?color=${color}&set=${set}`);
return new NextResponse(await res.blob(), {
headers: { "Content-Type": "image/svg+xml", "Cache-Control": "public, max-age=86400" },
});
}
Vue
<template><span v-html="svg" /></template>
<script setup>
import { ref, onMounted } from "vue";
const svg = ref("");
onMounted(async () => {
const res = await fetch(`/api/icons/home?color=7c9a82&size=32&set=lucide`);
svg.value = await res.text();
});
</script>
Svelte
<script>
export let name = "home";
let svg = "";
$: fetch(`/api/icons/${name}?color=7c9a82&set=tabler`).then(r=>r.text()).then(t=>svg=t);
</script>
<span>{@html svg}</span>
Python
import requests
# Family filtered
res = requests.get("https://hylab.vercel.app/api/icons", params={"set": "tabler", "limit": 20})
icons = res.json()["data"]
# Single icon
svg = requests.get("https://hylab.vercel.app/api/icons/home", params={"color": "7c9a82", "size": "32"}).text
# Search
icons = requests.get("https://hylab.vercel.app/api/icons/search", params={"q": "arrow"}).json()["data"]| Source | Icons | License |
|---|---|---|
| Tabler | 5,093 | MIT |
| Remix | 3,229 | Apache 2.0 |
| Carbon | 2,665 | Apache 2.0 |
| Lucide | 1,582 | ISC |
| Phosphor | 1,512 | MIT |
| Iconoir | 1,383 | MIT |
| BoxIcons | 814 | MIT |
| Octicons | 733 | MIT |
| CSS.gg | 704 | MIT |
| Heroicons | 324 | MIT |
Total: 18,039 icons · 14 categories · Shareable /browse?set=tabler&category=navigation
git clone https://github.com/onyxax/HyLab.git
cd HyLab
npm install
npm run dev
# http://localhost:3000Contributions welcome — open an issue or PR.
git checkout -b feat/my-feature
npm run build # must passMIT — free for personal and commercial use.
|
HyLab — The Icons API for Modern Apps |
Explore |
Resources
|
© 2026 HyLab · Icons from Tabler, Lucide, Heroicons & others — respective licenses apply. · Built by onyxax
