洪 民憙 (Hong Minhee) :nonbinary:'s avatar

洪 民憙 (Hong Minhee) :nonbinary:

@hongminhee@hollo.social

1,108 following1,898 followers

An intersectionalist, feminist, and socialist living in Seoul (UTC+09:00). @tokolovesme's spouse. Who's behind @fedify, @hollo, and @botkit. Write some free software in , , , & . They/them.

서울에 사는 交叉女性主義者이자 社會主義者. 金剛兔(@tokolovesme)의 配偶者. @fedify, @hollo, @botkit 메인테이너. , , , 等으로 自由 소프트웨어 만듦.

()

Pinned

@hongminhee@hollo.social

Hello! I'm Hong Minhee (洪 民憙), an open source software engineer in my late 30s, living in Seoul, Korea. I'm bisexual and non-binary (they/them), and an enthusiastic advocate of free/open source software and the fediverse.

I work full-time on @fedify, an ActivityPub server framework in TypeScript, funded by @sovtechfund. I'm also the creator of @hollo, a single-user ActivityPub microblog; @botkit, an ActivityPub bot framework; Hackers' Pub, a fediverse platform for software developers; and LogTape, a logging library for JavaScript and TypeScript.

I have a long interest in East Asian languages (CJK) and Unicode. I post mostly in English here, though occasionally in Japanese or in mixed-script Korean (國漢文混用體), a traditional writing style that interleaves Chinese characters with the native Korean alphabet. Wanting to write in that style was actually one of the reasons I joined the fediverse. Feel free to talk to me in English, Korean, Japanese, or even Literary Chinese!

en.wikipedia.org

Korean mixed script - Wikipedia

Pinned

はじめまして!ソウル在住の30代後半のオープンソースソフトウェアエンジニア、洪 民憙ホン・ミンヒと申します。バイセクシュアル(bisexual)・ノンバイナリー(non-binary)で、自由・オープンソースソフトウェア(F/OSS)とフェディバース(fediverse)の熱烈な支持者です。

STF(@sovtechfund)の支援を受け、TypeScript用ActivityPubサーバーフレームワーク「@fedify」の開発に専念しています。他にも、おひとり様向けのActivityPubマイクロブログ「@hollo」、ActivityPubボットフレームワーク「@botkit」、ソフトウェア開発者向けフェディバースプラットフォームHackers' Pub、JavaScript・TypeScript用ロギングライブラリLogTapeなどの制作者でもあります。

東アジア言語(いわゆるCJK)とUnicodeにも興味があります。このアカウントでは主に英語で投稿していますが、時々日本語や国漢文混用体(漢字ハングル混じり文)の韓国語でも書いています。実はこの文体で書きたくてフェディバースを始めた、という経緯もあります。日本語、英語、韓国語、漢文でも気軽に話しかけてください!

speakerdeck.com

国漢文混用体からHolloまで

本発表では、韓国語の「国漢文混用体」(漢字ハングル混じり文)を自分のフェディバース投稿に実装したいという小さな目標から始まった旅路を共有します。 この目標を達成するために、ActivityPubのJSON-LDの複雑さやHTTP Signatures、WebFingerなどの仕様を理解する必要性に…

Pinned

安寧(안녕)하세요! 저는 서울에 살고 있는 30() 後半(후반)의 오픈 소스 소프트웨어 엔지니어 洪民憙(홍민희)입니다. 兩性愛者(양성애자)(bisexual)이자 논바이너리(non-binary)이며, 自由(자유)·오픈 소스 소프트웨어(F/OSS)와 聯合宇宙(연합우주)(fediverse)의 熱烈(열렬)支持者(지지자)이기도 합니다.

STF(@sovtechfund)의 支援(지원)을 받아 TypeScript() ActivityPub 서버 프레임워크 @fedify 開發(개발)專業(전업)으로 ()하고 있습니다. 그 ()에도 싱글 유저() ActivityPub 마이크로블로그 @hollo, ActivityPub 봇 프레임워크 @botkit, 소프트웨어 開發者(개발자)를 위한 聯合宇宙(연합우주) 플랫폼 Hackers' Pub, JavaScript·TypeScript() 로깅 라이브러리 LogTape ()製作者(제작자)이기도 합니다.

()아시아 言語(언어)(이른바 CJK)와 Unicode에도 關心(관심)이 많습니다. 이 計定(계정)에서는 ()英語(영어)로 포스팅하지만, 때때로 日本語(일본어)國漢文混用體(국한문 혼용체) 韓國語(한국어)로도 씁니다. 聯合宇宙(연합우주)에 오게 된 動機(동기) () 하나가 바로 國漢文混用體(국한문 혼용체)로 글을 쓰고 싶었기 때문이기도 하고요. 韓國語(한국어), 英語(영어), 日本語(일본어), 아니면 漢文(한문)으로도 말을 걸어주세요!

logtape.org

LogTape

Unobtrusive logging library with zero dependencies—library-first design for Deno, Node.js, Bun, browsers, and edge functions

@hongminhee@hackers.pub

Smalltalk의 클래스 레퍼런스 문서는 스스로를 기술할 때 일인칭을 쓴다고 한다. “나는 추상 클래스입니다. 내 인스턴스들은 객체의 컬렉션입니다” 같은 식.

mastodon.social

Glyph (@glyph@mastodon.social)

@mcc @0xabad1dea@infosec.exchange all smalltalks do this; the idea is that each class speaks for itself, in the code as “self” and in the documentation as me/I. Twisted tried to adopt this idiom (my dad was a smalltalk programmer in the 80s, and it rubbed off a bit) but everyone else objected so much that it never caught on. I still wish it had.

@glyph@mastodon.social · Reply to mcc

@mcc @0xabad1dea all smalltalks do this; the idea is that each class speaks for itself, in the code as “self” and in the documentation as me/I. Twisted tried to adopt this idiom (my dad was a smalltalk programmer in the 80s, and it rubbed off a bit) but everyone else objected so much that it never caught on. I still wish it had.

@glyph@mastodon.social · Reply to mcc

@mcc @0xabad1dea all smalltalks do this; the idea is that each class speaks for itself, in the code as “self” and in the documentation as me/I. Twisted tried to adopt this idiom (my dad was a smalltalk programmer in the 80s, and it rubbed off a bit) but everyone else objected so much that it never caught on. I still wish it had.

@hongminhee@hackers.pub

FediDev KR 스프린트 두 번째 모임이 이번 주 토요일입니다! 아직 참가 신청 안 하신 분들은 늦지 않게 신청하시기 바랍니다.[1]


  1. 신청서 양식 마지막에 빈 입력란이 있는데 실수로 추가된 것입니다. 이벤터스에서 한 번 신청 양식을 정하면 수정할 수가 없다고 하네요. 그냥 아무 글자나 넣고 신청하시면 됩니다. ↩︎

hackers.pub

5월 24일(土) 한국 연합우주 개발자 모임(FediDev KR)에서 두 번째 스프린트 모임을 개최합니다! 장소는 뚝섬역 5번 출구쪽에 위치한 튜링의 사과(@TuringAppleDev)입니다. 참고로 스프린트 모임이란 함께 모여서 오픈 소스 코딩을 하는 자리인데, 한국 연합우주 개발자 모임의 스프린트에서는 새로운 연합우주 서비스나 앱을 개발하거나, 번역이나 문서에 기여하는 등 연합우주와 관련된 다양한 오픈 소스 활동을 모여서 함께 합니다. 지난 스프린트 모임의 기록을 스프린트 블로그(@sprints.fedidev.kr)에서 살펴보실 수 있습니다. 저는 그날 Fedify, Hollo, Hackers' Pub에 기여하시고자 하는 분들을 옆에서 도와드릴 예정입니다. Fedify, Hollo, Hackers' Pub에 기여해보고 싶었던 분들이 계시다면 모임에 참가하여 저와 함께 스프린트를 해보는 것도 좋을 것 같습니다. 이번 모임에 관심이 있으신 분은 행사 신청 페이지를 참고하시기 바랍니다.

5월 24일(土) 한국 연합우주 개발자 모임(FediDev KR)에서 두 번째 스프린트 모임을 개최합니다! 장소는 뚝섬역 5번 출구쪽에 위치한 튜링의 사과(@TuringAppleDev)입니다. 참고로 스프린트 모임이란 함께 모여서 오픈 소스 코딩을 하는 자리인데, 한국 연합우주 개발자 모임의 스프린트에서는 새로운 연합우주 서비스나 앱을 개발하거나, 번역이나 문서에 기여하는 등 연합우주와 관련된 다양한 오픈 소스 활동을 모여서 함께 합니다. 지난 스프린트 모임의 기록을 스프린트 블로그(@sprints.fedidev.kr)에서 살펴보실 수 있습니다. 저는 그날 Fedify, Hollo, Hackers' Pub에 기여하시고자 하는 분들을 옆에서 도와드릴 예정입니다. Fedify, Hollo, Hackers' Pub에 기여해보고 싶었던 분들이 계시다면 모임에 참가하여 저와 함께 스프린트를 해보는 것도 좋을 것 같습니다. 이번 모임에 관심이 있으신 분은 행사 신청 페이지를 참고하시기 바랍니다.

@hongminhee@hackers.pub

5월 24일(土) 한국 연합우주 개발자 모임(FediDev KR)에서 두 번째 스프린트 모임을 개최합니다! 장소는 뚝섬역 5번 출구쪽에 위치한 튜링의 사과(@TuringAppleDev)입니다.

참고로 스프린트 모임이란 함께 모여서 오픈 소스 코딩을 하는 자리인데, 한국 연합우주 개발자 모임의 스프린트에서는 새로운 연합우주 서비스나 앱을 개발하거나, 번역이나 문서에 기여하는 등 연합우주와 관련된 다양한 오픈 소스 활동을 모여서 함께 합니다. 지난 스프린트 모임의 기록을 스프린트 블로그(@sprints.fedidev.kr)에서 살펴보실 수 있습니다.

저는 그날 Fedify, Hollo, Hackers' Pub에 기여하시고자 하는 분들을 옆에서 도와드릴 예정입니다. Fedify, Hollo, Hackers' Pub에 기여해보고 싶었던 분들이 계시다면 모임에 참가하여 저와 함께 스프린트를 해보는 것도 좋을 것 같습니다.

이번 모임에 관심이 있으신 분은 행사 신청 페이지를 참고하시기 바랍니다.

event-us.kr

FediDev KR 스프린트 두 번째 모임 - 이벤터스

내가 원하는 행사를 개최하거나, 참여할 수 있는 플랫폼 - 이벤터스

@esurio1673@c.koliosky.com

正確にはNoteのUpdate ActorやQuestionのUpdateは対応してるはず
>RN

@tatmius@vivaldi.net

misskeyってupdate無いんだ(じゃあ俺がちょいちょい誤字を直してるのも伝わって無いのか)

@hongminhee@hollo.social

Misskeyがノートの編集機能を追加しないとしても、Update(Note)Update(Article)アクティビティを受信して適切に処理してくれる事を願っています。

아아~~~ 기여맛집 하나 더! 생겼습니다!!!
플러터로 만드는 마스토돈 클라이언트!! 잘하면 이번 반기안에 출시가 가능할지도!? 여러분의 기여가 함께 한다면 속도가 더 붙을지도 몰라요!?!?

플러터 앱 개인개발하고 있는거 생각보다 속도가 잘 붙고 있어서, 이번 fedidev kr 스프린트 모임에서 기여받을 수 있을 정도는 준비가 가능할 것 같습니다.... SNS 클론코딩이지만 클론코딩이 아닌 실제로 쓸 수 있는 플러터 기반의 소셜앱 만들고 싶은 분들 붙으세요,,

social.silicon.moe/@kodingwarr

social.silicon.moe

Jaeyeol Lee (a.k.a. kodingwarrior) :vim: (@kodingwarrior@silicon.moe)

Attached: 1 image 이 화면을..... 12분 컷으로 깎았다고...?

@foolfitz@social.slat.org · Reply to 洪 民憙 (Hong Minhee) :nonbinary:

@hongminhee
Indeed, East Asia (Japan, South Korea, Taiwan) currently lacks large foundations like NLnet or NGI that specifically fund open source projects.

NLnet primarily receives public funding from the EU's NGI program, while East Asian public sectors have relatively limited awareness and support for FOSS. I believe East Asian communities shouldn't overly expect "angel investments" from their public sectors;

a more realistic path might be: first strengthening through cross-national community collaboration, after which public sectors might follow with support.

These are just my rough thoughts on this topic.

@hongminhee@hackers.pub

We're pleased to announce the release of LogTape 0.10.0 today. This version introduces several significant enhancements to improve security, flexibility, and usability.

What is LogTape?

LogTape is a simple, zero-dependency logging library for JavaScript with support for multiple runtimes (Node.js, Deno, Bun, browsers, and edge functions). It features structured logging, hierarchical categories, template literals, and is designed to be used in both applications and libraries.

Key Highlights

New Data Redaction Package

The most notable addition in this release is the new @logtape/redaction package, designed to help protect sensitive information in your logs. This package provides two complementary approaches to redaction:

  • Pattern-based redaction: Uses regular expressions to identify and redact sensitive patterns like credit card numbers, email addresses, and tokens in formatted log output.
  • Field-based redaction: Identifies and redacts sensitive fields by their names in structured log data.

The package includes several built-in patterns for common sensitive data types:

  • Credit card numbers
  • Email addresses
  • JSON Web Tokens (JWTs)
  • U.S. Social Security numbers
  • South Korean resident registration numbers

Both approaches can be used independently or combined for maximum security. Comprehensive documentation for these features is available in the Data redaction section of the manual.

Timestamp Formatting Improvements

Text formatters now support omitting timestamps entirely from formatted messages. The TextFormatterOptions.timestamp option has been extended to include "none" and "disabled" values, giving you more control over log output format.

Lazy File Sink Option

A new FileSinkOptions.lazy option has been added, allowing file sinks to open files only when actually needed, which can improve resource utilization.

Config Error Detection

The configure() and configureSync() functions now check for duplicate logger configurations with the same category and throw a ConfigError when detected. This prevents unintended overriding of logger configurations.

Acknowledgments

We'd like to thank our external contributors who helped make this release possible:

  • Ooker for implementing the ability to omit timestamps from formatted messages (#35)
  • Rickey Ward for adding the lazy file sink option (#38, #39)

We encourage all users to upgrade to this version to take advantage of these improvements. As always, we welcome your feedback and contributions.


For more details on these changes, see the full changelog.

logtape.org

LogTape changelog | LogTape

Simple logging library with zero dependencies for Deno, Node.js, Bun, browsers, and edge functions

Fedifyは新しいパートナーシップの機会を探しています!

:fedify: Fedifyとは?

Fedifyは、ActivityPubベースのフェデレーションサーバーフレームワークで、開発者が分散型ソーシャルネットワークである)にアプリケーションを簡単に統合できるよう支援します。複雑なActivityPubプロトコルの実装を簡素化し、開発時間を大幅に短縮します。MITライセンスの下で提供されるオープンソースプロジェクトです。

💼 Fedifyを活用しているプロジェクト

すでに様々なプロジェクトがFedifyを活用しています:

  • Ghost:数百万人のユーザーを持つプロフェッショナルな出版プラットフォーム(MITライセンスのオープンソース)で、Fedifyの主要スポンサー兼パートナーです。
  • Hollo:個人ユーザー向けの軽量マイクロブログ(オープンソース、AGPL-3.0)
  • Hackers' Pub:ソフトウェアエンジニア向けのフェディバースブログプラットフォーム(オープンソース、AGPL-3.0)
  • Encyclia:ORCID学術記録をActivityPubを通じて提供するブリッジサービス

🚀 Fedifyが提供する価値

  • 開発時間80%削減:複雑なActivityPub実装の代わりに実証済みフレームワークを活用
  • 即時Fediverse互換性:Mastodon、Misskey、Pleroma、Pixelfed、PeerTubeなど様々なFediverseサービスとすぐに互換
  • 専門技術サポート:ActivityPubおよびフェデレーションプロトコルの専門家による直接サポート
  • カスタム開発:お客様の特定要件に合わせた機能開発

🤝 可能な協力モデル

  • カスタムコンサルティングと統合サポート:お客様のプラットフォームへのFedify統合のための専門的支援
  • カスタム機能開発:お客様のプラットフォームに必要な特定機能の開発と実装
  • 長期的な技術パートナーシップ:継続的な開発とメンテナンスのための長期協力関係

🌟 Fedifyとの協力によるメリット

  • 技術的優位性:自社開発と比較して時間とリソースの節約
  • ブランドイメージ:オープンソースエコシステムへの支援を通じた企業イメージの向上
  • 分散型ソーシャルネットワークへの参入:フェディバースエコシステムへの容易な参加
  • 競争優位性:ソーシャル機能による製品競争力の強化

📩 興味をお持ちですか?

ActivityPubの実装をご検討中の方や、Fedifyプロジェクトとの協力にご興味のある方は、ぜひご連絡ください:

お客様の要件と目標に合わせたカスタマイズされた協力の可能性を一緒に探りましょう。

github.com

GitHub - fedify-dev/fedify: ActivityPub server framework in TypeScript

ActivityPub server framework in TypeScript. Contribute to fedify-dev/fedify development by creating an account on GitHub.

Fedify는 새로운 후원 파트너를 찾고 있습니다!

:fedify: Fedify란?

Fedify는 기반 연합형 서버 프레임워크로, 개발자들이 분산형 소셜 네트워크인 ()에 애플리케이션을 쉽게 통합할 수 있도록 돕습니다. 복잡한 ActivityPub 프로토콜 구현을 단순화하여 개발 시간을 크게 단축시킵니다. MIT 라이선스 하에 제공되는 오픈 소스 프로젝트입니다.

💼 Fedify를 활용하는 프로젝트들

다양한 프로젝트들이 이미 Fedify를 활용하고 있습니다:

  • Ghost: 수백만 사용자를 보유한 전문적인 오픈 소스(MIT 라이선스) 퍼블리싱 플랫폼으로, Fedify의 주요 후원사이자 파트너입니다.
  • Hollo: 개인 사용자를 위한 경량 마이크로블로그 (오픈 소스, AGPL-3.0)
  • Hackers' Pub: 소프트웨어 엔지니어를 위한 연합우주 블로그 플랫폼 (오픈 소스, AGPL-3.0)
  • Encyclia: ORCID 학술 기록을 ActivityPub을 통해 제공하는 브리지 서비스

🚀 Fedify가 제공하는 가치

  • 개발 시간 80% 단축: ActivityPub의 복잡한 구현 대신 검증된 프레임워크 활용
  • 즉각적인 연합우주 호환성: Mastodon, Misskey, Pleroma, Pixelfed, PeerTube 등 다양한 연합우주 서비스와 즉시 호환
  • 전문 기술 지원: ActivityPub 및 연합 프로토콜 전문가의 직접 지원
  • 맞춤형 개발: 귀사의 특정 요구사항에 맞는 맞춤형 기능 개발

🤝 가능한 협력 모델

  • 맞춤형 컨설팅 및 통합 지원: 귀사 플랫폼에 통합을 위한 전문적 지원
  • 맞춤형 기능 개발 의뢰: 귀사에 필요한 특정 기능의 개발 및 구현
  • 장기적인 기술 파트너십: 지속적인 개발 및 유지보수를 위한 장기 협력 관계

🌟 Fedify와 협력했을 때의 이점

  • 기술적 이점: 자체 구현 대비 시간과 리소스 절약
  • 브랜드 이미지: 오픈 소스 생태계 지원을 통한 기업 이미지 강화
  • 분산형 소셜 네트워크 진입: 연합우주 생태계에 쉽게 참여
  • 경쟁 우위: 소셜 기능을 통한 제품 경쟁력 강화

📩 관심이 있으신가요?

ActivityPub 구현을 고려 중이시거나, Fedify 프로젝트와 협력하고 싶으시다면 연락 주세요:

귀사의 요구사항과 목표에 맞는 맞춤형 협력 방안을 함께 모색하겠습니다.

github.com

GitHub - fedify-dev/fedify: ActivityPub server framework in TypeScript

ActivityPub server framework in TypeScript. Contribute to fedify-dev/fedify development by creating an account on GitHub.

Fedify is looking for new partnership opportunities!

:fedify: What is Fedify?

is an -based federated server framework that helps developers easily integrate their applications with the , a decentralized social network. It simplifies the complex implementation of the ActivityPub protocol, significantly reducing development time. Fedify is an open-source project available under the MIT license.

💼 Projects using Fedify

Various projects are already leveraging Fedify:

  • Ghost: A professional publishing platform with millions of users, open source under MIT license, and a major sponsor and partner of Fedify.
  • Hollo: A lightweight microblogging platform for individual users (open source, AGPL-3.0)
  • Hackers' Pub: A fediverse blogging platform for software engineers (open source, AGPL-3.0)
  • Encyclia: A bridge service that makes ORCID academic records available via ActivityPub

🚀 Value provided by Fedify

  • 80% development time reduction: Utilize a proven framework instead of complex ActivityPub implementation
  • Immediate fediverse compatibility: Instant compatibility with various fediverse services including Mastodon, Misskey, Pleroma, Pixelfed, PeerTube, etc.
  • Expert technical support: Direct support from ActivityPub and Federation protocol experts
  • Custom development: Tailored feature development to meet your specific requirements

🤝 Potential collaboration models

  • Custom consulting and integration support: Professional assistance for integrating Fedify into your platform
  • Custom feature development: Development and implementation of specific features needed for your platform
  • Long-term technical partnership: Long-term collaboration for continuous development and maintenance

🌟 Benefits of collaborating with Fedify

  • Technical advantage: Save time and resources compared to in-house implementation
  • Brand image: Enhance corporate image through support of the open-source ecosystem
  • Entry to decentralized social networks: Easily participate in the fediverse ecosystem
  • Competitive edge: Strengthen product competitiveness through social features

📩 Interested?

If you're considering implementing ActivityPub or wish to collaborate with the Fedify project, please get in touch:

We're excited to explore customized collaboration opportunities that align with your requirements and goals.

github.com

GitHub - fedify-dev/fedify: ActivityPub server framework in TypeScript

ActivityPub server framework in TypeScript. Contribute to fedify-dev/fedify development by creating an account on GitHub.

@Native@pointless.chat
@hongminhee@hollo.social

愛好(애호)하는 簡化字(간화자)들:

  • ()()
  • ()()
  • ()()
  • ()()
  • ()()
  • ()()

For those interested in supporting 's development, we do have an Open Collective page where community is welcome.

Even small contributions help sustain development and show there's interest in open source tools. Thanks to our existing sponsors who've already been helping move the project forward!

The goal remains the same: make building federated applications more accessible to developers so the can continue to grow and thrive.

opencollective.com

Fedify - Open Collective

A TypeScript library for building federated server apps powered by ActivityPub and other standards, so-called fediverse.

@hongminhee@hollo.social

Just received word that @fedify wasn't selected for @nlnet's Open Call this round. While disappointing, I understand the competition was fierce with many worthy projects seeking limited funding.

The journey continues though— development will move forward at its own pace. Thanks to everyone who's shown interest and support for this project so far. Building tools for the remains important work, and I'm committed to seeing it through.

If you know of other funding opportunities that might be a good fit for open source tools, I'm all ears.

For those interested in supporting 's development, we do have an Open Collective page where community is welcome.

Even small contributions help sustain development and show there's interest in open source tools. Thanks to our existing sponsors who've already been helping move the project forward!

The goal remains the same: make building federated applications more accessible to developers so the can continue to grow and thrive.

opencollective.com

Fedify - Open Collective

A TypeScript library for building federated server apps powered by ActivityPub and other standards, so-called fediverse.

@hongminhee@hollo.social

Just received word that @fedify wasn't selected for @nlnet's Open Call this round. While disappointing, I understand the competition was fierce with many worthy projects seeking limited funding.

The journey continues though— development will move forward at its own pace. Thanks to everyone who's shown interest and support for this project so far. Building tools for the remains important work, and I'm committed to seeing it through.

If you know of other funding opportunities that might be a good fit for open source tools, I'm all ears.

@hongminhee@hollo.social

I implemented data redaction for today. The feature will be available through a dedicated package called @logtape/redaction (JSR & npm). It provides two complementary approaches to protect sensitive information in your logs:

  1. Pattern-based redaction: Uses regex patterns to identify and mask sensitive data in formatted log output
  2. Field-based redaction: Redacts properties by field names in structured log data

Looking forward to releasing this with LogTape 0.10.0 soon!

unstable.logtape.org

Data redaction | LogTape

Simple logging library with zero dependencies for Deno, Node.js, Bun, browsers, and edge functions

@grishka@socialhub.activitypub.rocks

This proposal describes an ActivityPub extension to allow actors to publish a short status text, with optional expiration, link attachment, and history.

Some centralized communication services provide their users with the ability to set a status on their account, which is usually displayed on their profile and sometimes next to their name in other places in the UI. These are distinct from regular posts because they can not be interacted with in any way whatsoever, can't contain media attachments, and usually have a short character limit on the order of several hundred characters at most. Statuses are always visible to anyone who can see the actor itself.

@hongminhee@hackers.pub

In the diverse and ever-evolving JavaScript ecosystem, logging remains a critical component for development, debugging, and monitoring applications. While numerous logging libraries exist, LogTape stands out with its unique combination of simplicity, flexibility, and cross-runtime compatibility. Let's explore why LogTape deserves consideration for your next JavaScript or TypeScript project—whether you're building an application or a library.

Zero Dependencies: A Lightweight Footprint

One of LogTape's most compelling features is its complete absence of dependencies. In an era where “dependency hell” plagues many JavaScript projects, LogTape offers a refreshing alternative:

// No additional packages to install beyond LogTape itself
import { configure, getConsoleSink, getLogger } from "@logtape/logtape";

This zero-dependency approach provides several advantages:

Reduced bundle size
No transitive dependencies means smaller packages
Enhanced stability
No risk of breaking changes from upstream dependencies
Simplified security
Fewer potential vulnerabilities from third-party code
Lower integration overhead
Particularly valuable for library authors who don't want to burden users with additional dependencies

Runtime Diversity: Write Once, Log Everywhere

While many popular logging libraries focus primarily on Node.js, LogTape provides seamless support across diverse JavaScript runtimes:

This runtime flexibility means you can use consistent logging patterns regardless of your deployment environment:

// Same API works seamlessly across all JavaScript runtimes
import { getLogger } from "@logtape/logtape";

const logger = getLogger(["my-service", "user-management"]);

// Works in Node.js, Deno, Bun, browsers, or edge functions
logger.info`User ${userId} logged in successfully`;

For teams working across multiple platforms or projects transitioning between runtimes, this consistency is invaluable. No need to learn different logging libraries or approaches—LogTape works the same way everywhere.

Hierarchical Categories: Fine-Grained Control

LogTape's hierarchical category system represents a standout feature that's surprisingly rare among JavaScript logging libraries. Categories allow you to organize logs in a tree-like structure:

// Parent category
const appLogger = getLogger(["my-app"]);

// Child category inherits settings from parent
const dbLogger = getLogger(["my-app", "database"]);

// Grandchild category
const queryLogger = getLogger(["my-app", "database", "queries"]);

// Alternative approach using getChild()
const userLogger = appLogger.getChild("users");
const authLogger = userLogger.getChild("auth");

This hierarchical approach offers powerful benefits:

Targeted filtering
Configure different log levels for different parts of your application
Inheritance
Child loggers inherit settings from parents, reducing configuration overhead
Organizational clarity
Logs naturally follow your application's module structure

Here's how you might configure logging levels for different categories:

await configure({
  sinks: {
    console: getConsoleSink(),
    file: getFileSink("app.log"),
  },
  loggers: [
    // Base configuration for all app logs
    { 
      category: ["my-app"], 
      lowestLevel: "info", 
      sinks: ["console", "file"] 
    },
    // More verbose logging just for database components
    { 
      category: ["my-app", "database"], 
      lowestLevel: "debug", 
      sinks: ["file"] 
    }
  ]
});

With this configuration, all application logs at "info" level and above go to both console and file, while database-specific logs include more detailed "debug" level information, but only in the log file.

Structured Logging: Beyond Simple Text

Modern logging goes beyond simple text strings. LogTape embraces structured logging, which treats log entries as data objects rather than plain text:

logger.info("User logged in", {
  userId: 123456,
  username: "johndoe",
  loginTime: new Date(),
  ipAddress: "192.168.1.1"
});

LogTape also supports placeholders in messages, connecting structured data with human-readable text:

logger.info("User {username} (ID: {userId}) logged in from {ipAddress}", {
  userId: 123456,
  username: "johndoe",
  ipAddress: "192.168.1.1"
});

Structured logging offers substantial benefits:

Improved searchability
Search for specific field values instead of parsing text
Better analysis
Perform data analysis on structured fields
Consistent format
Enforce standardized log formats
Machine-readable
Easier processing by log management systems

For performance-conscious applications, LogTape offers lazy evaluation of structured data:

logger.debug("Performance metrics", () => ({
  memoryUsage: process.memoryUsage(),
  cpuUsage: process.cpuUsage(),
  timestamp: performance.now()
}));

The function is only evaluated if the debug level is enabled, preventing unnecessary computation for suppressed log levels.

Extremely Simple Sinks and Filters: Minimal Boilerplate

LogTape's approach to extensibility is remarkably straightforward. Creating custom sinks (output destinations) and filters requires minimal boilerplate code.

Dead Simple Sinks

A sink in LogTape is just a function that receives a log record:

// Creating a custom sink is as simple as defining a function
const mySink = (record) => {
  const timestamp = new Date(record.timestamp).toISOString();
  const level = record.level.toUpperCase();
  const category = record.category.join('.');
  
  // Send to your custom destination
  myCustomLogService.send({
    time: timestamp,
    priority: level,
    component: category,
    message: record.message,
    ...record.properties
  });
};

// Use your custom sink in configuration
await configure({
  sinks: {
    console: getConsoleSink(),
    custom: mySink
  },
  loggers: [
    { category: ["my-app"], sinks: ["console", "custom"] }
  ]
});

Compare this with other libraries that require extending classes, implementing multiple methods, or following specific patterns. LogTape's approach is refreshingly straightforward.

Simple Filters

Similarly, filters in LogTape are just functions that return a Boolean:

// Filter that only passes high-priority or specific component logs
const importantLogsFilter = (record) => {
  // Always include errors
  if (record.level === "error" || record.level === "fatal") {
    return true;
  }
  
  // Always include payment-related logs
  if (record.category.includes("payments")) {
    return true;
  }
  
  // Filter out other logs
  return false;
};

await configure({
  // ...sinks configuration
  filters: {
    important: importantLogsFilter
  },
  loggers: [
    { 
      category: ["my-app"], 
      sinks: ["alertSystem"], 
      filters: ["important"] 
    }
  ]
});

LogTape also provides a convenient shorthand for level-based filtering:

await configure({
  // ...sinks configuration
  filters: {
    // This creates a filter for "warning" level and above
    warningAndAbove: "warning"
  },
  loggers: [
    { 
      category: ["my-app"], 
      sinks: ["console"], 
      filters: ["warningAndAbove"] 
    }
  ]
});

Perfect for Library Authors

LogTape is uniquely well-suited for library authors who want to incorporate logging without burdening their users. The core philosophy is simple:

  1. Libraries provide logging output points
  2. Applications configure how those logs are handled

Here's how a library might implement LogTape:

// my-awesome-lib/database.js
import { getLogger } from "@logtape/logtape";

export class Database {
  private logger = getLogger(["my-awesome-lib", "database"]);

  constructor(host, port, user) {
    this.host = host;
    this.port = port;
    this.user = user;
  }

  connect() {
    this.logger.info("Connecting to database", {
      host: this.host,
      port: this.port,
      user: this.user
    });
    
    // Connection logic...
    
    this.logger.debug("Connection established");
  }
  
  query(sql) {
    this.logger.debug("Executing query", { sql });
    // Query logic...
  }
}

The key point is that the library never calls configure(). Instead, it provides useful log output points with appropriate levels and contextual data.

Applications using the library can then decide exactly how to handle these logs:

// Application code
import { configure, getConsoleSink } from "@logtape/logtape";
import { Database } from "my-awesome-lib";

// Configure how logs should be handled
await configure({
  sinks: {
    console: getConsoleSink(),
    file: getFileSink("app.log")
  },
  loggers: [
    // Handle all library logs
    { 
      category: ["my-awesome-lib"], 
      lowestLevel: "info", 
      sinks: ["file"] 
    },
    // More verbose for database component during development
    { 
      category: ["my-awesome-lib", "database"], 
      lowestLevel: "debug", 
      sinks: ["console", "file"] 
    }
  ]
});

// Use the library
const db = new Database("localhost", 5432, "user");
db.connect();

This separation of concerns offers several benefits:

  1. Library users have complete control over log handling
  2. Libraries can provide rich logging without imposing implementation details
  3. No risk of conflict with application logging configurations
  4. Libraries can be "noisy" internally while allowing applications to filter as needed

Contexts for Richer Logging

LogTape provides context mechanisms for adding consistent properties across multiple log messages. This is particularly valuable for tracing requests through a system:

Explicit Contexts

const logger = getLogger(["my-app", "api"]);

// Create a logger with context
const requestLogger = logger.with({
  requestId: "abc-123",
  userId: 42,
  endpoint: "/users"
});

// All logs from this logger include the context properties
requestLogger.info("Processing request");
requestLogger.debug("Validating input");
requestLogger.info("Request completed", { durationMs: 120 });

Implicit Contexts (v0.7.0+)

For cases where you want context to apply across function calls without explicit passing:

import { getLogger, withContext } from "@logtape/logtape";

function handleRequest(req, res) {
  withContext({ 
    requestId: req.id, 
    userId: req.user?.id 
  }, () => {
    // All logs within this function and any functions it calls
    // will automatically include the context properties
    processRequest(req, res);
  });
}

function processRequest(req, res) {
  // No need to pass context - it's automatically available
  getLogger(["my-app", "processor"]).info("Processing data");
  
  // Call other functions that will also inherit the context
  validateInput(req.body);
}

function validateInput(data) {
  // This log also gets the requestId and userId
  getLogger(["my-app", "validator"]).debug("Validating input", { data });
}

This implicit context capability is invaluable for tracing requests through multiple layers of code without manually threading context through every function call.

When LogTape Might Not Be Your Best Choice

While LogTape offers compelling advantages for many use cases, it's not universally the best choice:

Extreme performance requirements
If your application logs tens of thousands of entries per second and raw performance is the top priority, specialized high-performance libraries like Pino may be more suitable with their focus on optimized logging throughput.
Extensive pre-built integrations
If you need immediate integration with numerous specific systems (Elasticsearch, Graylog, etc.) without writing any custom code, Winston's rich ecosystem of transports might provide a faster starting point.
Legacy systems with specific logging requirements
If you're maintaining systems built around specific logging patterns from Java or other environments, purpose-built libraries like Log4js might offer more familiar APIs.
Web browser-only applications with minimal logging needs
For extremely simple web browser-only logging needs where you just want basic console output with levels, even simpler libraries like loglevel might be sufficient.

Conclusion

LogTape stands out in the crowded JavaScript logging landscape by offering a unique combination of features that address real-world development challenges:

  • Zero dependencies for a lightweight, secure foundation
  • Runtime diversity supporting Node.js, Deno, Bun, browsers, and edge functions
  • Hierarchical categories for better log organization and filtering
  • Structured logging for improved analysis and searchability
  • Simple extension mechanisms with minimal boilerplate
  • Library-friendly design that respects separation of concerns

Whether you're building applications or libraries, working across multiple JavaScript runtimes, or simply seeking a clean, well-designed logging solution, LogTape deserves serious consideration. Its thoughtful design balances simplicity with powerful features, avoiding common pitfalls of JavaScript logging libraries.

For more information and detailed documentation, visit LogTape's official website.

logtape.org

LogTape

Simple logging library with zero dependencies for Deno, Node.js, Bun, browsers, and edge functions