@nema-international/icons
v0.5.0
Published
Nema International icon library — 2,531 tree-shakeable SVG icons in 28 categories, 271 country flags in 5 styles with 15 flag packs, and Font Awesome Free, with RTL support.
Maintainers
Readme
@nema/icons
مكتبة أيقونات Nema International — أكثر من 2,000 أيقونة SVG مبنية على Lucide، تعمل مع أي إطار عمل، وتدعم الاتجاه من اليمين لليسار (RTL) للواجهات العربية.
Nema International's icon library — 2,531 core icons in 28 categories, 271 country flags and 2,883 Font Awesome icons based on Lucide, framework-agnostic, tree-shakeable, with built-in RTL support.
Install in your app
The package isn't on the public npm registry, so you install it from a file (or your own private registry).
1. Build the package file (in this folder):
npm install
npm run release # builds, tests and creates nema-icons-0.5.0.tgz2. Install it in your app. Copy the .tgz into your project (e.g. a vendor/ folder, committed to git) and run:
npm install ./vendor/nema-icons-0.5.0.tgzTo update later, build a new version, replace the file and run the same command. For a team, publish it to a private registry instead (GitHub Packages or a private npm org): npm publish --access restricted, then npm install @nema/icons.
Angular (17.1+)
- Copy
node_modules/@nema/icons/integrations/angular/nema-icon.component.tsinto your app, e.g.src/app/shared/. - Import it in a standalone component and pass icon objects:
import { Component } from '@angular/core';
import { NemaIconComponent } from './shared/nema-icon.component';
import { Wallet, Send, BrandWhatsapp } from '@nema/icons';
import { FlagIq } from '@nema/icons/flags';
@Component({
selector: 'app-transfer',
standalone: true,
imports: [NemaIconComponent],
template: `
<button><nema-svg [icon]="Send" [size]="18" /> Send money</button>
<nema-svg [icon]="FlagIq" [size]="16" shape="rounded" [outline]="true" />
<nema-svg [icon]="BrandWhatsapp" color="brand" label="WhatsApp" />
`,
})
export class TransferComponent {
Send = Send; FlagIq = FlagIq; BrandWhatsapp = BrandWhatsapp;
}Only the icons you import are bundled. Arrows mirror automatically under dir="rtl". If TypeScript can't find @nema/icons/flags, set "moduleResolution": "bundler" in tsconfig.json (the default since Angular 17).
Alternative for icon names that come from data: import '@nema/icons/element' in main.ts, add CUSTOM_ELEMENTS_SCHEMA, then <nema-icon [attr.name]="item.icon">. This bundles the whole core set (~430 KB).
React Native (iOS & Android)
- Install the SVG renderer:
npx expo install react-native-svg # Expo
npm install react-native-svg && cd ios && pod install # bare React Native- Use the
NemaIconcomponent:
import { NemaIcon } from '@nema/icons/react-native';
import { Wallet, ArrowRight, BrandWhatsapp } from '@nema/icons';
import { FlagIq } from '@nema/icons/flags';
import { FlagSquareAe } from '@nema/icons/flags-square';
<NemaIcon icon={Wallet} size={22} color="#0d7363" />
<NemaIcon icon={ArrowRight} /> {/* mirrors when I18nManager.isRTL */}
<NemaIcon icon={BrandWhatsapp} color="brand" accessibilityLabel="WhatsApp" />
<NemaIcon icon={FlagIq} size={18} shape="wave" outline />
<NemaIcon icon={FlagSquareAe} size={28} shape="circle" outline />Props: icon, size, color (default black; 'brand' for logo colours), strokeWidth, shape, outline, rtl, accessibilityLabel, style.
Notes for React Native:
- Subpath imports (
@nema/icons/flags) need Metro package exports, on by default since React Native 0.79. On older versions addconfig.resolver.unstable_enablePackageExports = truetometro.config.js. - Metro doesn't tree-shake, so importing from
@nema/iconsadds the core set (~800 KB) to the app. Flags and Font Awesome are only added if you import from their entries. - The web component (
@nema/icons/element),createElementandreplaceIconsare browser-only; useNemaIconinstead.
React (web)
toSvg returns a string, so render it with dangerouslySetInnerHTML (the SVG comes from the package, not users):
const Icon = ({ icon, ...o }) => <span style={{ display: 'inline-flex' }} dangerouslySetInnerHTML={{ __html: toSvg(icon, o) }} />;1. Named imports (recommended — only the icons you use are bundled)
import { House, Send, Wallet, toSvg, createElement } from '@nema/icons';
toSvg(House); // SVG string
toSvg(Wallet, { size: 20, color: '#0a7', strokeWidth: 1.5 });
toSvg(Send, { title: 'Send money' }); // accessible: role="img" + aria-label
toSvg(Send, { dir: 'rtl' }); // mirrored for Arabic layouts
document.body.append(createElement(House)); // live SVGElementExport names are PascalCase of the Lucide name: arrow-right → ArrowRight, arrow-down-0-1 → ArrowDown0_1.
2. Web component (Angular, React, Vue, plain HTML)
import '@nema/icons/element';<nema-icon name="wallet" size="20" color="#0a7"></nema-icon>
<nema-icon name="send" label="Send money"></nema-icon>
<div dir="rtl">
<nema-icon name="arrow-right"></nema-icon> <!-- automatically mirrored -->
</div>Angular: add CUSTOM_ELEMENTS_SCHEMA to the component/module schemas, and import '@nema/icons/element' in main.ts.
React / TSX: works as-is; for typed props declare nema-icon in JSX.IntrinsicElements.
3. Names from data at runtime
import { renderIcon, getIcon, iconNames, replaceIcons } from '@nema/icons/all';
renderIcon(menuItem.icon, { size: 18 }); // throws on unknown names
getIcon('house'); // IconDef | undefined
replaceIcons(); // turns <i data-icon="house"></i> into SVG
@nema/icons/allincludes every icon (~430 KB min). Use it only when names come from a database/CMS.
4. SVG sprite (no JavaScript)
<svg width="24" height="24"><use href="/node_modules/@nema/icons/sprite.svg#house"/></svg>What's included
| Entry | Contents | Licence |
|---|---|---|
| @nema/icons | 2,531 core icons: Lucide outline set, 16 hand-drawn arrows, Latin & Arabic letters and digits, 138 brand logos, Nema icons | ISC / CC0 / OFL |
| @nema/icons/categories | 28 curated categories (below) | — |
| @nema/icons/flags | 271 country & region flags (4:3), 15 flag packs, country data | MIT |
| @nema/icons/flags-square | the same 271 flags as square (1:1) artwork, for circles and avatars | MIT |
| @nema/icons/fontawesome | Font Awesome Free 7: 2,001 solid, 273 regular, 609 brands | CC BY 4.0 — credit required |
Flags and Font Awesome are separate entries so they never inflate your main bundle.
Categories
import { categories } from '@nema/icons/categories';
categories['contact-us'].icons; // ['phone', 'phone-call', …, 'brand-whatsapp']essential · interface · contact-us · social-network · social-media-logos · messaging-apps · media-platforms · home-screen-apps · creative-software · multimedia · office · business · business-analytics · web-marketing · digital-marketing · strategy · planning-calendars · health-care · computer-hardware · learning · mentoring-training · real-estate · arrows · hand-drawn-arrows · alphabet-numbers · arabic-alphabet · miscellaneous · nema
Country flags & flag packs
import { FlagIq, getFlag, getFlagPack, flagPacks, flagInfo, toSvg } from '@nema/icons/flags';
import { FlagSquareIq } from '@nema/icons/flags-square';
toSvg(FlagIq, { size: 18 }); // 24×18 rectangle
toSvg(FlagIq, { size: 18, shape: 'rounded', outline: true }); // rounded corners + faint edge
toSvg(FlagIq, { size: 18, shape: 'wave' }); // waving flag with fabric shading
toSvg(FlagSquareIq, { size: 24, shape: 'circle' }); // circle (use the square artwork)
getFlag(user.countryCode); // 'IQ', 'ae', 'flag-gb' all work
getFlagPack('gcc'); // IconDef[] for the pack
flagInfo('iq'); // { name: 'Iraq', nameAr: 'العراق', capital: 'Baghdad', currency: ['IQD'], phone: ['+964'], continent: 'Asia', languages: [...] }Styles: rect (default), rounded, wave, circle via the shape option; square artwork from @nema/icons/flags-square. outline: true keeps white flags (Japan, Cyprus) visible on white.
Packs (flagPacks): arab-league · gcc · nema-corridors (GB, IQ, AE) · uk-nations · eu · g7 · g20 · organisations · africa · asia · europe · north-america · south-america · oceania · antarctica. Each has title, titleAr and codes. Edit FLAG_PACKS in scripts/sets.mjs to add your own.
Bundle size: named imports (FlagIq) are tree-shaken to a few KB each. getFlag() and getFlagPack() look flags up by name, so they include all 271 (~2 MB). Use them for full country pickers, and named imports elsewhere. flagInfo() adds about 48 KB of country data.
Every flag's keywords include its Arabic name, ISO code, currency, capital and dialling code, so a country picker can search "العراق", "IQD" or "+964".
To use flags in <nema-icon>: registerIcons(flags) (or squareFlags) from @nema/icons/all, then <nema-icon name="flag-iq" shape="wave" outline>.
Font Awesome
import { FaSolidHouse, FaBrandsLinkedin, toSvg } from '@nema/icons/fontawesome';
toSvg(FaBrandsLinkedin, { size: 20, color: '#0A66C2' });Names are fa-<solid|regular|brands>-<name>. Font Awesome Brands covers logos missing from Simple Icons, such as LinkedIn, Slack, Microsoft, Amazon and OpenAI. CC BY 4.0: credit "Font Awesome Free" in your app or site.
Alphabet, numbers & hand-drawn arrows
letter-a…letter-z,number-0…number-9, each also as-circleand-squarebadges.- Arabic:
ar-letter-alef…ar-letter-yeh(28 letters) andar-number-0…ar-number-9(٠–٩), same three shapes. hand-arrow-right,-left,-up,-down,-curve-right,-curve-down,-loop,-squiggle,-double,-circle,-zigzag,-spiral,-bounce,-swoosh,-return,-point. Directional ones mirror in RTL.
Social media icons
138 filled brand logos from Simple Icons (CC0), all named brand-<platform>, grouped into social media, messaging, media platforms, home screen apps and creative software. Social media includes:
Facebook, Instagram, X, TikTok, YouTube, Snapchat, Pinterest, Reddit, Threads, Bluesky, Mastodon, Tumblr, Quora, VK, BeReal, Clubhouse, WhatsApp, Telegram, Messenger, Signal, WeChat, Viber, LINE, Discord, iMessage, Zalo, Zoom, Twitch, Kick, Vimeo, Spotify, SoundCloud, Medium, Substack, Behance, Dribbble, GitHub, GitLab, Google, Apple, Google Play, App Store, Google Maps, Linktree.
import { BrandWhatsapp, BrandInstagram, toSvg } from '@nema/icons';
toSvg(BrandWhatsapp); // inherits text colour
toSvg(BrandWhatsapp, { color: 'brand' }); // official colour #25D366<nema-icon name="brand-instagram" color="brand"></nema-icon>Brand icons are filled rather than stroked, carry the extra class nema-icon-brand, ignore strokeWidth, and never mirror in RTL.
LinkedIn, Slack, Microsoft, Adobe, Canva, Amazon and OpenAI are not in Simple Icons at their owners' request. Use the Font Awesome Brands versions where they exist (fa-brands-linkedin, fa-brands-slack…), or add official logos to brand-icons/ (see the README there).
Logos are trademarks of their owners; follow each brand's guidelines.
Options
| Option | Default | Description |
|---|---|---|
| size | 24 | width/height (number = px, or any CSS length) |
| color | currentColor | icon colour — inherits text colour by default; 'brand' uses a brand icon's official colour |
| strokeWidth | 2 | line thickness |
| absoluteStrokeWidth | false | keep line thickness constant when resizing |
| className | — | extra CSS classes (every icon also gets nema-icon nema-icon-<name>) |
| title | — | accessible label; without it the icon is aria-hidden |
| shape | rect | flags only: rounded, circle or wave |
| outline | false | flags only: faint edge for light flags on light backgrounds |
| dir | ltr | rtl mirrors the 101 direction-aware icons (arrows, chevrons, send, reply, undo…) |
Development
npm install
npm run build # regenerate from lucide-static, type-check, bundle to dist/
npm testTo update icons: npm update lucide-static simple-icons flag-icons @fortawesome/fontawesome-free && npm run build.
To change categories or brand groups: edit scripts/sets.mjs (names are validated at build time).
To add your own icons: put 24×24 stroke SVGs in custom-icons/ and rebuild. A file named like a Lucide icon overrides it. An example, nema-transfer.svg → NemaTransfer, is included.
Licence
ISC for the package. Artwork: Lucide (ISC), Simple Icons (CC0), flag-icons (MIT), Font Awesome Free (CC BY 4.0, attribution required), letters outlined from Inter and Noto Sans Arabic (OFL 1.1), hand-drawn arrows and Nema icons original (ISC). Logos are trademarks of their owners. Full notices in LICENSE.
