npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@teamturing/icons

v2.6.0

Published

Icon components for React based project

Readme

@teamturing/icons

React 프로젝트용 아이콘 컴포넌트. 세 갈래로 나뉜다.

| 엔트리 | 내용 | 형태 | 앞으로 | | --- | --- | --- | --- | | @teamturing/icons | 구 자사 아이콘 291개 | 두꺼운 면, fill="currentColor" | 동결 | | @teamturing/icons/lucide | lucide 1776개 | 선, stroke-width="2" | 업스트림 버전 업 | | @teamturing/icons/gpai | GPAI 디자인 시스템 아이콘 16개 | 얇은 외곽선 중심, fill="currentColor" | 신규 추가 |

import { SearchIcon } from '@teamturing/icons';
import { SearchIcon as LucideSearchIcon } from '@teamturing/icons/lucide';

세 갈래 다 Icon 접미사를 쓴다. 이름이 겹치면 한 파일에서 함께 쓸 때 별칭이 필요하다. 별칭을 써도 번들에는 아무것도 더해지지 않는다.

lucide 이름은 공식 문서의 이름에 접미사만 붙인 형태다. searchSearchIcon, trash-2Trash2Icon.

엔트리끼리는 서로를 참조하지 않는다. 자사 아이콘만 쓰는 앱의 번들에는 lucide 코드가 한 바이트도 들어가지 않는다.

세 갈래를 가르는 것은 스타일이다

"어느 아이콘 세트에 있느냐"가 아니라 어느 디자인 언어로 그려졌느냐로 나뉜다. gpai는 디자이너가 새로 그리고 있는 GPAI 디자인 시스템의 아이콘이고, 루트 291개는 그 이전 세대다. 같은 개념을 다시 그린 것이 있어 이름이 겹친다.

새로 필요한 아이콘이 생겼다
├─ GPAI 디자인 시스템에 있다   →  svg/gpai/ 에 넣는다 (yarn svgr)
└─ 없다 (범용 · 임시)          →  @teamturing/icons/lucide 에서 가져다 쓴다
                                  거기에도 없으면 lucide-static 버전을 올려 본다

루트 svg/의 291개는 동결이다. 새 아이콘을 그쪽에 넣지 않는다. 기존 아이콘의 형태를 고치는 것은 되지만, 목록이 늘어나지는 않는다.

이름이 겹치는 아이콘

현재 gpai 16개 중 10개가 루트에 같은 이름으로 있다 — AiSquareIcon, ArrowCurvedIcon, ArrowElbowIcon, EyesTwoIcon, LandscapeArrowIcon, PortraitArrowIcon, RootXIcon, ThunderIcon, TwinkleIcon, YoutubeIcon. 전부 같은 개념을 새 스타일로 다시 그린 것이다. 새로 쓰는 화면이라면 gpai 쪽을 고른다.

import { TwinkleIcon } from '@teamturing/icons/gpai';                  // 새 스타일
import { TwinkleIcon as LegacyTwinkleIcon } from '@teamturing/icons';  // 구 스타일

한 화면에 두 세대를 섞으면 선 두께가 눈에 띄게 어긋나므로, 화면 단위로 한쪽을 고른다.

lucide와 겹치는 것은 BaselineIcon·BoldIcon 둘이고, 루트와 lucide 사이에는 72개가 겹친다.

gpai는 브랜드 네임스페이스이기도 하다. packages/token-studio가 색을 gpai/aisaac으로 나누는 것과 같은 구분이고, 아이콘도 같은 축을 따른다.

버전

2.0.0부터 lucide가 포함된다. 코드 상으로 깨지는 변경은 없으므로 1.x에서 올라올 때 고칠 것은 없다. 자사 아이콘만 쓰던 앱은 import를 그대로 두면 되고, 번들도 그대로다 (두 엔트리가 서로를 참조하지 않는다).

메이저를 올린 것은 패키지의 성격이 달라졌다는 신호다. 291개짜리 자사 전용 패키지에서 2060개짜리 두 갈래 패키지가 됐고, 앞으로 lucide 업스트림의 아이콘 제거·개명이 이 패키지의 메이저 사유가 된다.

하지 말 것 — 네임스페이스 import

// ✅ 아이콘 하나당 1KB 남짓
import { SearchIcon } from '@teamturing/icons/lucide';

// ❌ 1.07MB — lucide 전체가 번들에 들어간다
import * as Lucide from '@teamturing/icons/lucide';
const Icon = Lucide[iconName];

번들러는 어떤 키가 쓰일지 정적으로 알 수 없으면 전부 남길 수밖에 없다. 이름을 런타임에 정해야 한다면 네임스페이스 대신 필요한 아이콘만 담은 맵을 직접 만든다.

import { SearchIcon, SettingsIcon, Trash2Icon } from '@teamturing/icons/lucide';

const ICONS = { search: SearchIcon, settings: SettingsIcon, trash: Trash2Icon };
const Icon = ICONS[iconName];

lucide의 선 두께

lucide의 stroke-width="2"24px로 그렸을 때 기준이다. 16px나 20px로 줄이면 선도 같은 비율로 얇아져 자사 아이콘 옆에서 흐리게 보인다. 필요하면 strokeWidth로 보정한다.

<SearchIcon width={16} height={16} strokeWidth={3} />

react-kit을 쓴다면 StyledIconstrokeWidth prop이 같은 일을 한다.

라이선스

이 패키지의 코드는 MIT다. @teamturing/icons/lucide의 아이콘은 lucide에서 파생된 것으로 ISC를 따르고, 그중 search·check·calendar처럼 Feather 프로젝트에서 파생된 약 110개는 별도의 MIT(Copyright (c) 2013-present Cole Bemis)를 따른다.

두 라이선스 모두 저작권 표시와 허가 문구를 사본에 유지할 것을 조건으로 한다. 그래서 THIRD-PARTY-NOTICES.md에 전문을 싣고, 빌드 산출물의 lucide 모듈마다 @license 배너를 붙인다. 배너를 엔트리에만 붙이면 트리셰이킹이 배럴을 걷어낼 때 표시도 함께 사라지므로, 상류인 lucide-react와 마찬가지로 아이콘 파일마다 붙인다.

자사 아이콘 쪽에는 붙지 않는다. lucide를 쓰지 않는 번들에 lucide 표시가 들어가면 그것대로 잘못된 출처 표시이기 때문이다.

아이콘 추가·갱신

yarn svgr         # svg/ 와 svg/gpai/ → src/ 와 src/gpai/
yarn svgr:lucide  # lucide-static → src/lucide/

SVGR은 svg/ 아래 폴더 구조를 그대로 보존하고 폴더마다 index.ts를 따로 생성한다. 그래서 gpai 아이콘은 svg/gpai/에 넣기만 하면 되고, 명령은 기존 yarn svgr 그대로다. 루트 src/index.ts는 하위 폴더의 아이콘을 끌어오지 않으므로 두 엔트리가 섞이지 않는다.

디자이너 export가 맞춰야 할 것은 세 가지다. 24×24 캔버스, viewBox="0 0 24 24", 그리고 단색 아이콘은 #8D94A0으로 그려져 있을 것. #8D94A0currentColor로 치환되므로 다른 색으로 넘어오면 에러 없이 그대로 통과하고, 나중에 color가 안 먹는 것으로 드러난다. 여러 색으로 그려진 아이콘은 그대로 두고 이름에 -color를 붙인다.

파일명은 svg/gpai/에서 kebab-case(chart-area-stacked.svg), 루트 svg/에서는 snake_case다. SVGR이 양쪽 다 같은 이름으로 정규화하므로(ChartAreaStackedIcon) 결과는 같지만, 폴더 안에서는 섞지 않는다.

src/·src/gpai/·src/lucide/.tsx생성물이지만 커밋한다. 빌드가 생성 단계에 의존하지 않아 CI에서 결과가 갈리지 않고, 릴리스에 실제로 무엇이 들어가는지 PR에서 보인다.

yarn svgr 끝에 verify-icons.mjs가 돌아 대소문자 충돌·viewBox 유실·Icon 접미사· index와 파일 불일치를 검사한다. gpai 아이콘에 색이 하드코딩돼 있으면 경고를 남긴다 (color를 상속하지 못한다 — 다만 여러 색으로 그려진 아이콘이면 정상이므로 실패시키지는 않는다).

lucide 원본 svg만은 커밋하지 않는다. lucide의 search.svg가 디자이너의 search.svg와 이름이 겹치는 데다, 1700개가 넘는 원본을 리포에 넣을 이유도 없다. lucide-static 의존성에서 그때그때 읽어 .lucide-svg/(gitignore)에 모은 뒤 변환한다.

lucide 버전을 올릴 때는 yarn svgr:lucide를 다시 돌린다. 마지막의 verify-lucide.mjs가 개수·export 이름 중복·대소문자 충돌·viewBox 유실을 검사하고 어긋나면 빌드를 멈춘다. 업스트림에서 아이콘이 제거되거나 이름이 바뀌면 breaking change이므로 feat(icons)!로 커밋한다.

브랜드 폴더를 더 만들려면

aisaac 등을 추가할 때는 svg/aisaac/를 만들고 세 곳에 한 줄씩 더하면 된다.

  • package.jsonexports./aisaac, typesVersionsaisaac
  • rollup.config.jsentry('src/aisaac/index.ts', 'dist/aisaac')
  • tsconfig.esm.jsonfiles./src/aisaac/index.ts

scripts/verify-icons.mjsTARGETS에도 추가한다. SVGR·gen_icon.sh 쪽은 손댈 것이 없다.