2025: 나는 3개의 OSS 프로젝트를 배포했다 — “사실 괜찮았다”
I’m happy to help translate the article, but I’ll need the full text you’d like translated. Could you please paste the content of the article (excluding the source line you already provided) here? Once I have the text, I’ll translate it into Korean while preserving the original formatting, markdown syntax, and technical terms.
안녕하세요, 여러분!
저는 프론트엔드 엔지니어, @nyaomaru 입니다.
최근 다이어트를 위해 10 kg가 넘는 배낭을 메고 산책을 하고 있는데, 마치 드래곤볼의 마스터 로시(카메‑센닌) 훈련처럼요 🐢.
또 한 해가 훌쩍 지나고 나서야 깨달았습니다…
벌써 연말이 다가왔습니다.
연말에는 청소, 쇼핑, 그리고 회고를 합니다.
일본어로 12월을 “시와스(師走)” 라 하는데, “선생님들조차 바빠서 달린다”는 뜻이라고 합니다.
저는 너무 많이 뛰어다녀서 완전히 닳아버린 걸레가 된 기분입니다.
어쨌든, 올해의 잡동사니를 올해 안에 정리하고 생각도 정리해봅시다 🧹.
그래서 저는 2025년을 제가 릴리즈한 OSS 프로젝트 관점에서 되돌아보고자 합니다.
Note: 여기에는 바이럴 성공 사례가 없습니다.
🎯 2025년에 릴리즈한 OSS 프로젝트
올해 저는 다음 세 가지 OSS 프로젝트를 릴리즈했습니다:
| 프로젝트 | 스크린샷 | 레포 |
|---|---|---|
is-kit | ![]() | |
changelog-bot | ![]() | |
divider | ![]() |
저는 이들 모두를 계속 유지보수하고 업데이트를 릴리즈하고 있습니다.
🤔 왜 만들었을까?
간단히 말하면: 내가 직접 필요했기 때문입니다.
| 프로젝트 | 동기 |
|---|---|
is-kit | “사용자 정의 타입 가드를 더 깔끔하게 작성할 방법이 있을 거야…” |
changelog-bot | “매번 CHANGELOG.md를 작성하는 게 솔직히 귀찮아…” |
divider | “문자열을 더 깔끔하게 나누고 싶어…” |
각 프로젝트는 작은 불편함에서 시작되었습니다. 저는 스스로에게 물었습니다, “이 불편함을 어떻게 없앨 수 있을까?” 그리고 바로 구현을 시작했습니다.
물론 다른 사람이 내 OSS를 사용해 주면 좋지만, 제 주된 초점은 언제나 **‘내 문제를 제대로 해결할 수 있느냐’**였습니다.
각 프로젝트를 간단히 되돌아보겠습니다.
Source: …
is-kit
TypeScript를 사용한다면 사용자 정의 타입 가드를 꽤 자주 작성할 것입니다.
Before is-kit
type User = {
id: string;
age: number;
role: 'admin' | 'guest' | 'trial';
};
function isUser(value: unknown): value is User {
if (typeof value !== 'object' || value === null) return false;
const record = value as Record;
return (
typeof record.id === 'string' &&
typeof record.age === 'number' &&
(record.role === 'admin' ||
record.role === 'guest' ||
record.role === 'trial')
);
}
계속 생각했어요: “이걸 더 간단하게 할 수 없을까?”
그때 LEGO 블록이라는 아이디어가 떠올랐습니다: 작은 논리 조각들을 조합해서 복잡한 가드를 만드는 것이죠.
After is-kit
import { struct, isString, isNumber, oneOfValues } from 'is-kit';
const isUser = struct({
id: isString,
age: isNumber,
role: oneOfValues('admin', 'guest', 'trial'),
});
더 선언적이고, 더 읽기 쉬우며, 여전히 타입‑안전합니다 — 멋지지 않나요?
가드를 더 조합할 수도 있습니다:
import { and, narrowKeyTo, predicateToRefine } from 'is-kit';
type AdminUser = Readonly & { role: 'admin' };
const byRole = narrowKeyTo(isUser, 'role');
const isAdminUser = byRole('admin');
const isAdultAdmin = and(
isAdminUser,
predicateToRefine((user: AdminUser) => user.age >= 18)
);
is-kit을 사용하면서 좋았던 점
- 많은 사람들이 사용해보고 별점을 줬습니다 – 정말 감사드려요 🙏🙏🙏
- TypeScript 타입 정의를 테스트할 수 있는
tsd라이브러리를 발견했는데, 실제로 사용해보니 정말 재미있었습니다. - API가 비교적 단순하게 유지됐고, 전반적으로 결과에 만족합니다.
계획 중인 개선 사항
- 더 많은 기본 프리셋
- 더 많은 컴바이너
struct와 관련된 추가 개선
마음에 드신다면 ⭐️ 하나 눌러 주세요!
목표는 마법 같은 기능이 아니라 — 조합성과 가독성을 높이는 것이었습니다.
changelog-bot
OSS 프로젝트를 릴리즈할 때 보통 릴리즈 노트를 작성하고 CHANGELOG.md를 업데이트합니다.
하지만… 좀 번거롭죠? 적어도 저에게는 그랬어요 🤮
전통적인 커밋 규칙을 기반으로 changelog를 자동 생성해 주는 도구도 있지만, 저는 이렇게 생각했어요:
“AI가 내용에 따라 변경 사항을 분류할 수 있을까?”
그 질문이 **changelog-bot**을 만들게 했습니다.
OpenAI 또는 Anthropic API 키를 사용해 CLI에서 사용할 수 있습니다 (AI는 선택 사항).
(간략히 생략 – 원문에는 사용 예시, 작동 방식, 향후 계획 등이 이어집니다.)
마무리 생각
2025년은 제 개인 OSS 툴박스에 있어 생산적인 한 해였습니다.
바이럴 성공은 없었지만, 각 프로젝트가 저에게 실제 문제를 해결해 주었고, 커뮤니티의 피드백이 저를 계속 동기부여했습니다.
코드와 삶 모두에서 더 깔끔하고 체계적인 2026을 기대합니다! 🎉
깨끗하게 정리하고, 즐겁게 코딩하세요!
CI‑Driven Changelog Updates
It’s mainly designed to run in CI.
Once a release is published, your CHANGELOG.md can be updated automatically.
name: Update Changelog
on:
release:
types: [published]
jobs:
changelog:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: nyaomaru/changelog-bot@v0
with:
changelog-path: CHANGELOG.md
base-branch: main
provider: openai
release-tag: ${{ github.event.release.tag_name }}
release-name: ${{ github.event.release.tag_name }}
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
You can also run it locally via CLI if you want. Details are in the README.
What Worked Well with changelog‑bot
- It completely removed the manual effort of maintaining
CHANGELOG.mdfor my projects. - Releasing became much easier 🚀
- I personally enjoyed designing the preprocessing logic that extracts and scores features before passing data to the AI.
That said, there’s still room for improvement, and contributions are welcome!
One note though:
Writing changelogs became easier. But… life itself didn’t magically become easier.
That part is still under observation.
Source:
divider – 문자열을 깔끔하게 자르는 방법
때때로 substring을 사용해 문자열을 계속 자르다 보면 코드가 지저분해집니다.
좀 더 깔끔한 방법이 필요해서 divider를 만들었어요. 이 라이브러리를 사용하면 인덱스를 한 번에 지정해 문자열을 분할할 수 있습니다.
import { divider } from '@nyaomaru/divider';
const [a, b, c] = divider(text, 3, 6);
divider를 통해 배운 점
- 훌륭한 엔지니어가 기여해 주었고, 진심으로 감사합니다 🙏
- OSS 관리 기본을 배웠습니다:
CODE_OF_CONDUCT.md,CONTRIBUTING.md,CHANGELOG.md,DEVELOPER.md등
하지만 명확한 단점도 있었습니다. string.split()에 비해 큰 장점을 보여주지 못했거든요.
그 점은 별점 수에서도 드러났고, 솔직히 설계 실수였다고 생각합니다.
요약하면, 이 프로젝트는 **“유용한 실패”**였습니다.
그럼에도 불구하고 값진 학습 경험이었고, 만들게 되어 기쁩니다.
✨ 2026년 목표
2025년 하이라이트
- OSS 프로젝트 출시
- 기술 기사 작성 시작
- 네덜란드로 이주 🇳🇱
새로운 도전으로 가득한 한 해였습니다.
2026년을 바라보며
- DSA와 관련된 OSS 애플리케이션 출시
- 작은 게임 프로젝트 공개
하지만 무엇보다도, 나의 주요 목표는 간단합니다:
번아웃되지 말고, 계속 나아가세요. 🏃♂️
이는 OSS, 시스템, 그리고 삶 전반에 적용됩니다.
읽어 주셔서 감사하고, 멋진 한 해가 되시길 바랍니다.
2026년에 뵙겠습니다 🐈


