배그로 설명하는 수학, 실험, 과학의 관계
수학: 배그에서 총을 쏠 때 총알 궤적
실험: 현실에서 총을 쏘면 배그와 동일한 총알 궤적이 나올까? 궁금한데? 쏴서 비교해보자!
과학: 실험 몇 번 해보니까 배그랑 현실이랑 총알 궤적이 같더라! 앞으로 총알 궤적 예측할 때는 배그켜서 확인하자!
@kodingwarrior@hackers.pub · 694 following · 509 followers
Neovim Super villain. 풀스택 엔지니어 내지는 프로덕트 엔지니어라고 스스로를 소개하지만 사실상 잡부를 담당하는 사람. CLI 도구를 만드는 것에 관심이 많습니다.
Hackers' Pub에서는 자발적으로 바이럴을 담당하고 있는 사람. Hackers' Pub의 무궁무진한 발전 가능성을 믿습니다.
그 외에도 개발자 커뮤니티 생태계에 다양한 시도들을 합니다. 지금은 https://vim.kr / https://fedidev.kr 디스코드 운영 중
배그로 설명하는 수학, 실험, 과학의 관계
수학: 배그에서 총을 쏠 때 총알 궤적
실험: 현실에서 총을 쏘면 배그와 동일한 총알 궤적이 나올까? 궁금한데? 쏴서 비교해보자!
과학: 실험 몇 번 해보니까 배그랑 현실이랑 총알 궤적이 같더라! 앞으로 총알 궤적 예측할 때는 배그켜서 확인하자!
Gemini 2.5 Pro and Flash now have the ability to return image segmentation masks on command, as base64 encoded PNGs embedded in JSON strings
I vibe coded an interactive tool for exploring this new capability - it costs a fraction of a cent per image https://simonwillison.net/2025/Apr/18/gemini-image-segmentation/
@kodingwarriorJaeyeol Lee 저는 잘 보이는데, 아마 팔로를 안 하셔서 타임라인에 안 뜨는 게 아닐까요?
@hongminhee洪 民憙 (Hong Minhee) 팔로를 하고는 있는데 이상하네요
토요일/일요일 각각 카테고리를 나눠서 작업하게 될 것 같습니다.
이미 postgres 기반으로 데이터베이스 세팅해서 만들고 있는게 있긴 하지만, Vibe coding으로 쭉 이어나가다가 Fedify를 제대로 활용하는 방법에 대해 알지 못한 상황이라 중간에 삑사리나서 헤매고 있는 상황입니다.
큰 욕심은 안내고 천천히 튜토리얼을 정주행하면서 전반적으로 한 사이클 돌고 감을 잡는 것에 의미를 둘 생각입니다. 예제는 sqlite를 쓰고 있지만, 여기서도 배리에이션 안주고 최대한 예제를 충실히 따르면서 완주하고 배리에이션은 천천히 주려고 합니다.
django admin에서 아티클 url을 수동으로 입력하고 langchain 기반으로 요약하는 기능 PoC로 나마 구현해보려고 합니다.
RE: https://hackerspub-ask-bot.deno.dev/message/0196468d-7fd8-7447-b2a6-e974c49e42b8
https://hackerspub-ask-bot.deno.dev/message/0196468d-7fd8-7447-b2a6-e974c49e42b8 살아는 있는데 이게 왜 해커스펍에 안보이지
@kodingwarriorJaeyeol Lee 어떤 연합 동아리에서 장고를 학생들에게 전파했더라고요 viva Django
@z9mb1Jiwon 너무 특정되네요 ㅋㅋ
학교 캡스톤에서 절반 넘는 팀이 장고를 사용하는 신세카이를 보셨나요? 나도 멋진거 만들고 싶은데 현실적인거 고려하니까 걍 crud 웹앱이 되어버려서 눈물 난다
@z9mb1Jiwon 훌륭하네요 (Django 좋아하는 사람)
확실히 문서에 잘 정리해놓으니까 AI랑 협업하기가 수월한 것 같음. 개인 프로젝트에도 잘 해놓으면 아주 좋겠구먼
@joonnotnotJoon Use Repomix
llms.txt 는 누가 쪼개주나?
@minhoryang repomix 같은걸 쓴다던가...?
가장 선호하는 JetBrains IDE가 AI 시대에 뒤쳐지고 있어서 안타까웠는데 AI assistant 와 Junie 업데이트로 이제 좀 쓸만해진 것 같다.
여전히 부족한 점이 많기는 하다.
Agent는 느리고, 현재 상태에 대한 가시성이 없어 계속 기다려야할지 중단하고 새로운 세션을 열어야 할지에 대한 판단이 안선다.
prompt를 별도 관리할 수 있게 한 점은 훌륭하나 포맷이나 디렉토리를 유저가 선택할 수 있게 했더라면 더욱 유용했을 것이다. 나는 prompt가 다른 에이전트와 공유 가능하길 원한다.
vscode copilot처럼 Claude로부터 mcp 서버 설정을 불러올 수 있다. 하지만 역시 현재 상태 가시성이 없어 제대로 mcp 서버와 인터랙션이 되고 있는지 확인하기 어렵다.
그럼에도 불구하고 Cursor 나 Copilot에 충분히 대항할만한 업데이트라 생각한다. 앞으로를 응원한다!
https://www.jetbrains.com/ko-kr/junie/
Concurrency in Haskell: Fast, Simple, Correct
Link: https://bitbashing.io/haskell-concurrency.html
Discussion: https://news.ycombinator.com/item?id=43679906
실무에 바로 적용하는 웹 접근성 가이드북 - 접근성의 개념부터 태그 의미 있게 사용하기, WAI-ARIA, 리액트 컴포넌트 만들기까지 (김남경, 곽규현 (지은이) / 제이펍 / 2025-05-01 / 42,000원) https://feed.kodingwarrior.dev/r/PJHgZJ
http://www.aladin.co.kr/shop/wproduct.aspx?ItemId=362558470&partner=openAPI&start=api
멀티패러다임 프로그래밍 - 객체지향, 함수형, 명령형의 통합적 사고로 구현하는 소프트웨어 설계와 구현 (유인동 (지은이) / 한빛미디어 / 2025-04-21 / 38,000원) https://feed.kodingwarrior.dev/r/JDRhIG
http://www.aladin.co.kr/shop/wproduct.aspx?ItemId=362548794&partner=openAPI&start=api
What Every Programmer Should Know about How CPUs Work • Matt Godbolt • GOTO 2024 https://lobste.rs/s/dbkvz5 #video #performance
https://www.youtube.com/watch?v=-HNpim5x-IE
PostHog 뉴스레터는 중소규모 팀 맞춤형(즉, 사이드프로젝트 물주는 사람들한테도 좋은..)으로 좋은 내용이 많아서 새 글이 올라올때마다 여기에도 자주 공유하고 싶음
오늘도 PostHog 뉴스레터의 좋은 말씀 들고왔습니다
빠른 제품 출시(Ship Fast)를 가로막는 7가지 원인 그리고 이에 대한 해결방법 https://newsletter.posthog.com/p/this-is-why-youre-not-shipping
징후: 문제가 생겨도 1:1 미팅 때까지 해결을 미룸
1:1 미팅 축소 및 목적 변경 (상태 보고 → 전략 논의/피드백)징후: 다른 팀 승인 없이는 일이 앞으로 나아가지 못함
징후: 팀이나 담당자(오너십)를 바꾸는 것이 매우 힘듦
징후: 엔지니어보다 영업 인력이 눈에 띄게 많음 (Sales-led)
징후: 정보 공유가 안 돼서 계속 사람들을 '챙겨야' 함 ('in the loop')
Pull 방식 문화 정착 (필요한 사람이 직접 확인)징후: 성과가 그저 그런 사람들이 회사를 떠나지 않음
'키퍼 테스트' 등 활용한 정기적 성과 점검 및 피드백PIP) 지양징후: 모든 일이 너무 예상대로만 흘러가고 편안함 (위험 감수 X)
와! 해커스펍! 모바일 글쓰기 프리뷰 기능!
가장 좋아하는 動物은?
@hongminhee洪 民憙 (Hong Minhee)
아니 언제 투표기능이 들어간거에요 ㅋㅋㅋㅋ
Jaeyeol Lee shared the below article:
Ailrun (UTC-5/-4) @ailrun@hackers.pub
이 글은 함수형 언어의 핵심 개념을 람다 대수를 통해 소개하며, 함수형 언어의 평가 방식에 대한 깊이 있는 이해를 제공합니다. 람다 대수의 기본 요소인 변수, 함수, 함수 호출을 설명하고, 값에 의한 호출(CBV)과 이름에 의한 호출(CBN)의 차이점을 명확히 분석합니다. 특히, 폴 블레인 레비의 "값 밀기에 의한 호출(CBPV)"을 소개하며, 이 방식이 CBV와 CBN을 모두 포괄할 수 있는 강력한 도구임을 강조합니다. CBPV가 함수와 함수 호출을 스택 기반으로 어떻게 다르게 해석하는지, 그리고 이를 통해 람다 대수를 기계 수준으로 컴파일할 때 얻을 수 있는 이점을 설명합니다. 항수 분석과 같은 최적화 기법을 CBPV를 통해 어떻게 더 명확하게 표현할 수 있는지 보여주며, GHC 컴파일러의 중간 언어로서 CBPV의 중요성을 부각합니다. 이 글은 함수형 언어의 깊은 이론적 배경과 실제 컴파일러 구현 사이의 연결고리를 탐구하고자 하는 독자에게 유용한 통찰력을 제공합니다.
Read more →다른 분들이 여러 가지 말씀을 해 주셨습니다만 저도 첨언하자면,
"의업과 약업의 현실적 관계"도 한 가지 중대한 이유입니다. 제약회사 직원이 의사에게 굽실거리다 못해 예비군 훈련을 대신 가거나, 수술을 대신 한다는 기상천외한 뉴스 다들 한번쯤 보셨을 텐데요.
원론적으로는 의사가 약에도 빠삭해야 하지만, 현실적으로는 자기 전공분야도 너무 방대하고 약학도 너무 방대해서 그러기 어렵습니다. 마치 소프트웨어 엔지니어 중에 하드웨어 덕질까지 하는 경우는 소수이고 대부분은 그냥 맥북 사는 것과 비슷하게, 의사들의 약 지식도 한계가 있는 거죠. 어떤 약을 안 쓰는 게 무슨 이유가 있어서가 아니라 진짜로 그 약의 존재를 몰라서인 경우가 허다합니다. 그러니 약 성능 똑같아도 영업에 따라 억 단위가 왔다갔다 하고, 그러니 제약회사의 영업이 엽기뉴스의 영역으로 가는 것이죠.
이런 시장환경에서 의사들에게 약 이름과 성분 이름의 대조표를 매년 새로 외우라고 하면 망하겠죠? 그래서 어떻게든 이름만 보면 성분을 알게 하려고 발버둥치는 것입니다.
그러면 반대로 성분명과 전혀 무관한 약 이름은 어떻게 나오는지도 짐작이 되시죠? 그렇습니다. "처방전 필요없는" 약은 성분명 쿨하게 버리고 일반소비자에게 호소하는 작명을 하는 경향이 있습니다. 그리고, 처방전이 필요하더라도 동일성분의 약이 많거나 저네릭 경쟁이 벌어지는 경우에도 튀는 이름으로 차별화를 꾀하는 경향이 있죠.
RE: https://serafuku.moe/notes/a6lapo16c2
약간 Deprecated 상태인 Deno Fresh 프로젝트 주워먹긴 했는데, Deno Fresh + Supabase 조합으로 MVP 뽑는거 진짜 금방이네......... express로는 그냥 백엔드 위주로 MVP 뽑아먹는 느낌이었다면, deno fresh는 preact가 자체적으로 붙어있어서 제품 사이클 전반적으로 MVP 뽑아먹기 적합한 스택임
@ailrunAilrun (UTC-5/-4)
@kodingwarriorJaeyeol Lee
@lionhairdino 아아 어떤 느낌인지 상상이 갑니다. 저는@parksb
님이 하신것처럼 맥주가 차있으면 좋겠다싶어 H 중간 막대를 위로 올렸습니다.
H가 컵이고, P가 손잡이어야 하는데, H가 컵 모양이 잘 안나와서, 포기하고 그냥 맥주에 담가 버렸습니다. (근데 호스트분 아주 근거리에 디자이너분 계신 거 아닌가 모르겠습니다.)
@ailrunAilrun (UTC-5/-4)
@kodingwarriorJaeyeol Lee 아니 왜 리스프... (학부때 재미있긴 했지만요 ㅋ)
@ysh염산하 둘의 단점도 합쳐져있습니다 🥲
@bglbgl gwyng
@kodingwarriorJaeyeol Lee
@lionhairdino
제 심상이랑은 좀 다르네요. 저는 H의 중간 막대가 좀 아래로, H가 좌우로 살짝 벌어져있고 P가 좀 더 바짝 붙은 형태를 상상했습니다. Inkscape 켜서 직접 그리기에는 졸리네요 😅
@ailrunAilrun (UTC-5/-4)
@lionhairdino
@kodingwarriorJaeyeol Lee
@bglbgl gwyng 지나가다 보고 아이디어가 넘 좋아서 살포시...
살다살다 fennel을 긱뉴스에서 보게 될 줄은
왜 Fennel인가?
------------------------------
- Fennel 은 Lua 런타임에서 실행되는 프로그래밍 언어임
- Lua 는 간단하면서도 강력한 프로그래밍 언어로, 다른 프로그램에 쉽게 통합되어 사용자에게 재프로그래밍 가능성을 제공함
- Fennel 은 Lua의 단점을 보완하여, 보다 명확하고 오류를 줄이는 대안을 제공함
- Fennel 은 Lisp 계열의 문법을 사용하여…
------------------------------
https://news.hada.io/topic?id=20336&utm_source=googlechat&utm_medium=bot&utm_campaign=1834
Jaeyeol Lee replied to the below article:
JakeSeo @jakeseo@hackers.pub
새로운 블로그의 시작을 알리는 첫 글입니다. 간단한 자기소개와 함께 블로그를 시작하게 된 계기와 앞으로의 방향에 대한 기대감을 표현하고 있습니다. 독자들에게 친근하게 다가가려는 노력이 돋보이며, 앞으로 어떤 이야기들이 펼쳐질지 궁금하게 만듭니다.
Read more →
@jakeseo 와아 반가워요
@eunjoJoeun Kim 안녕하세요! 반갑습니다!
이제 이렇게 던져놓고, 나는 이거보다 더 잘 만들 자신이 있다 하는 분들에게 아이디어 던지고 턴 종료(?)
헐...... Gemini한테 해커스펍 로고 뽑아달라고 했는데, 요렇게 나옴.,.....
https://www.svgviewer.dev/s/LOJBa27c 대박. 정방형 로고도 만들어짐
헐...... Gemini한테 해커스펍 로고 뽑아달라고 했는데, 요렇게 나옴.,.....
@bglbgl gwyng
@lionhairdino
@ailrunAilrun (UTC-5/-4)
오.... 저 방금 SVG를 LLM이 깎아줄 수 있다는걸 방금 처음 알았어요.
https://www.svgviewer.dev/s/sCwe91Tw https://www.svgviewer.dev/s/8hMjXLcz https://www.svgviewer.dev/s/c4oIyOId
@bglbgl gwyng
@lionhairdino
@ailrunAilrun (UTC-5/-4)
이제 이걸 디자인 감각 있는 분 호출해서 벡터그래픽으로 만들어달라하면 될 것 같은데......
바이브코딩 어제 예시를 한 4개 정도 만들어봤는데, 간단한 예시를 만드는것 자체는 30분-2시간 컷으로 빠르게 프로토타이핑이 되는 것 같음.
2048 게임이라던가 경품추첨 레이싱 게임이라던가(three.js가 들어간) 카지노 룰렛
요렇게 만들어봤는데 너무 잘만들어줘서 소름돋을 지경임.
이제 이걸 페디버스 앱을 만들 수 있을 정도로 뚝딱뚝딱 만드는데 활용할 수 있을지는 모르겠다
지금까지 Hackers' Pub은 반드시 이메일을 통해 로그인 링크를 수신하는 식으로만 로그인이 가능했는데, 사실은 많이 번거로웠죠?
이를 해결하기 위해 Hackers' Pub에 패스키 기능을 추가했습니다. 패스키 추가는 설정 → 패스키 페이지에서 할 수 있으며, 패스키가 등록된 기기 및 브라우저에서는 로그인 페이지에서 자동적으로 패스키를 사용할 것인지 묻는 창이 뜨게 됩니다.
Ditch the DIY Drama: Why Use Fedify Instead of Building ActivityPub from Scratch? https://lobste.rs/s/ebab2d #distributed #web
https://hackers.pub/@hongminhee/2025/why-use-fedify
Jaeyeol Lee shared the below article:
洪 民憙 (Hong Minhee) @hongminhee@hackers.pub
So, you're captivated by the fediverse—the decentralized social web powered by protocols like ActivityPub. Maybe you're dreaming of building the next great federated app, a unique space connected to Mastodon, Lemmy, Pixelfed, and more. The temptation to dive deep and implement ActivityPub yourself, from the ground up, is strong. Total control, right? Understanding every byte? Sounds cool!
But hold on a sec. Before you embark on that epic quest, let's talk reality. Implementing ActivityPub correctly isn't just one task; it's like juggling several complex standards while riding a unicycle… blindfolded. It’s hard.
That's where Fedify comes in. It's a TypeScript framework designed to handle the gnarliest parts of ActivityPub development, letting you focus on what makes your app special, not reinventing the federation wheel.
This post will break down the common headaches of DIY ActivityPub implementation and show how Fedify acts as the super-powered pain reliever, starting with the very foundation of how data is represented.
At its core, ActivityPub relies on the ActivityStreams 2.0 vocabulary to describe actions and objects, and it uses JSON-LD as the syntax to encode this vocabulary. While powerful, this combination introduces significant complexity right from the start.
First, understanding and correctly using the vast ActivityStreams vocabulary itself is a hurdle. You need to model everything—posts (Note, Article), profiles (Person, Organization), actions (Create, Follow, Like, Announce)—using the precise terms and properties defined in the specification. Manual JSON construction is tedious and prone to errors.
Second, JSON-LD, the encoding layer, has specific rules that make direct JSON manipulation surprisingly tricky:
Note objects mean the same thing regarding the name property:// No name property
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Note",
"content": "…"
}
// Equivalent to:
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Note",
"name": [],
"content": "…"
}
content property here:// Single value
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Note",
"content": "Hello"
}
// Equivalent to:
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Note",
"content": ["Hello"]
}
Announce activities are semantically equivalent (assuming the URIs resolve correctly):{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Announce",
// Embedded objects:
"actor": {
"type": "Person",
"id": "http://sally.example.org/",
"name": "Sally"
},
"object": {
"type": "Arrive",
"id": "https://sally.example.com/arrive",
/* ... */
}
}
// Equivalent to:
{
"@context":
"https://www.w3.org/ns/activitystreams",
"type": "Announce",
// URI references:
"actor": "http://sally.example.org/",
"object": "https://sally.example.com/arrive"
}
Attempting to manually handle all these vocabulary rules and JSON-LD variations consistently across your application inevitably leads to verbose, complex, and fragile code, ripe for subtle bugs that break federation.
Fedify tackles this entire data modeling challenge with its comprehensive, type-safe Activity Vocabulary API. It provides TypeScript classes for ActivityStreams types and common extensions, giving you autocompletion and compile-time safety. Crucially, these classes internally manage all the tricky JSON-LD nuances. Fedify's property accessors present a consistent interface—non-functional properties (like tags) always return arrays, functional properties (like content) always return single values or null. It handles object references versus embedded objects seamlessly through dereferencing accessors (like activity.getActor()) which automatically fetch remote objects via URI when needed—a feature known as property hydration. With Fedify, you work with a clean, predictable TypeScript API, letting the framework handle the messy details of AS vocabulary and JSON-LD encoding.
Once you can model data, you need to make your actors discoverable. This primarily involves the WebFinger protocol (RFC 7033). You'd need to build a server endpoint at /.well-known/webfinger capable of parsing resource queries (like acct: URIs), validating the requested domain against your server, and responding with a precisely formatted JSON Resource Descriptor (JRD). This JRD must include specific links, like a self link pointing to the actor's ActivityPub ID using the correct media type. Getting any part of this wrong can make your actors invisible.
Fedify simplifies this significantly. It automatically handles WebFinger requests based on the actor information you provide through its setActorDispatcher() method. Fedify generates the correct JRD response. If you need more advanced control, like mapping user-facing handles to internal identifiers, you can easily register mapHandle() or mapAlias() callbacks. You focus on defining your actors; Fedify handles making them discoverable.
// Example: Define how to find actors
federation.setActorDispatcher(
"/users/{username}",
async (ctx, username) => { /* ... */ }
);
// Now GET /.well-known/webfinger?resource=acct:username@your.domain just works!
Serving actor profiles requires careful content negotiation. A request for an actor's ID needs JSON-LD for machine clients (Accept: application/activity+json) but HTML for browsers (Accept: text/html). Handling incoming activities at the inbox endpoint involves validating POST requests, verifying cryptographic signatures, parsing the payload, preventing duplicates (idempotency), and routing based on activity type. Implementing collections (outbox, followers, etc.) with correct pagination adds another layer.
Fedify streamlines all of this. Its core request handler (via Federation.fetch() or framework adapters like @fedify/express) manages content negotiation. You define actors with setActorDispatcher() and web pages with your framework (Hono, Express, SvelteKit, etc.)—Fedify routes appropriately. For the inbox, setInboxListeners() lets you define handlers per activity type (e.g., .on(Follow, ...)), while Fedify automatically handles validation, signature verification, parsing, and idempotency checks using its KV Store. Collection implementation is simplified via dispatchers (e.g., setFollowersDispatcher()); you provide logic to fetch a page of data, and Fedify constructs the correct Collection or CollectionPage with pagination.
// Define inbox handlers
federation.setInboxListeners("/inbox", "/users/{handle}/inbox")
.on(Follow, async (ctx, follow) => { /* Handle follow */ })
.on(Undo, async (ctx, undo) => { /* Handle undo */ });
// Define followers collection logic
federation.setFollowersDispatcher(
"/users/{handle}/followers",
async (ctx, handle, cursor) => { /* ... */ }
);
Sending an activity requires more than a simple POST. Networks fail, servers go down. You need robust failure handling and retry logic (ideally with backoff). Processing incoming activities synchronously can block your server. Efficiently broadcasting to many followers (fan-out) requires background processing and using shared inboxes where possible.
Fedify addresses reliability and scalability using its MessageQueue abstraction. When configured (highly recommended), Context.sendActivity() enqueues delivery tasks. Background workers handle sending with automatic retries based on configurable policies (like outboxRetryPolicy). Fedify supports various queue backends (Deno KV, Redis, PostgreSQL, AMQP). For high-traffic fan-out, Fedify uses an optimized two-stage mechanism to distribute the load efficiently.
// Configure Fedify with a persistent queue (e.g., Deno KV)
const federation = createFederation({
queue: new DenoKvMessageQueue(/* ... */),
// ...
});
// Sending is now reliable and non-blocking
await ctx.sendActivity({ handle: "myUser" }, recipient, someActivity);
Securing an ActivityPub server is critical. You need to implement HTTP Signatures (draft-cavage-http-signatures-12) for server-to-server authentication—a complex process. You might also need Linked Data Signatures (LDS) or Object Integrity Proofs (OIP) based on FEP-8b32 for data integrity and compatibility. Managing cryptographic keys securely is essential. Lastly, fetching remote resources risks Server-Side Request Forgery (SSRF) if not validated properly.
Fedify is designed with security in mind. It automatically handles the creation and verification of HTTP Signatures, LDS, and OIP, provided you supply keys via setKeyPairsDispatcher(). It includes key management utilities. Crucially, Fedify's default document loader includes built-in SSRF protection, blocking requests to private IPs unless explicitly allowed.
The fediverse is diverse. Different servers have quirks. Ensuring compatibility requires testing and adaptation. Standards evolve with new Federation Enhancement Proposals (FEPs). You also need protocols like NodeInfo to advertise server capabilities.
Fedify aims for broad interoperability and is actively maintained. It includes features like ActivityTransformers to smooth over implementation differences. NodeInfo support is built-in via setNodeInfoDispatcher().
Beyond the protocol, building any server involves setup, testing, and debugging. With federation, debugging becomes harder—was the message malformed? Was the signature wrong? Is the remote server down? Is it a compatibility quirk? Good tooling is essential.
Fedify enhances the developer experience significantly. Being built with TypeScript, it offers excellent type safety and editor auto-completion. The fedify CLI is a powerful companion designed to streamline common development tasks.
You can quickly scaffold a new project tailored to your chosen runtime and web framework using fedify init.
For debugging interactions and verifying data, fedify lookup is invaluable. It lets you inspect how any remote actor or object appears from the outside by performing WebFinger discovery and fetching the object's data. Fedify then displays the parsed object structure and properties directly in your terminal. For example, running:
$ fedify lookup @fedify-example@fedify-blog.deno.dev
Will first show progress messages and then output the structured representation of the actor, similar to this:
// Output of fedify lookup command (shows parsed object structure)
Person {
id: URL "https://fedify-blog.deno.dev/users/fedify-example",
name: "Fedify Example Blog",
published: 2024-03-03T13:18:11.857Z, // Simplified timestamp
summary: "This blog is powered by Fedify, a fediverse server framework.",
url: URL "https://fedify-blog.deno.dev/",
preferredUsername: "fedify-example",
publicKey: CryptographicKey {
id: URL "https://fedify-blog.deno.dev/users/fedify-example#main-key",
owner: URL "https://fedify-blog.deno.dev/users/fedify-example",
publicKey: CryptoKey { /* ... CryptoKey details ... */ }
},
// ... other properties like inbox, outbox, followers, endpoints ...
}
This allows you to easily check how data is structured or troubleshoot why an interaction might be failing by seeing the actual properties Fedify parsed.
Testing outgoing activities from your application during development is made much easier with fedify inbox. Running the command starts a temporary local server that acts as a publicly accessible inbox, displaying key information about the temporary actor it creates for receiving messages:
$ fedify inbox
✔ The ephemeral ActivityPub server is up and running: https://<unique_id>.lhr.life/
✔ Sent follow request to @<some_test_account>@activitypub.academy.
╭───────────────┬─────────────────────────────────────────╮
│ Actor handle: │ i@<unique_id>.lhr.life │
├───────────────┼─────────────────────────────────────────┤
│ Actor URI: │ https://<unique_id>.lhr.life/i │
├───────────────┼─────────────────────────────────────────┤
│ Actor inbox: │ https://<unique_id>.lhr.life/i/inbox │
├───────────────┼─────────────────────────────────────────┤
│ Shared inbox: │ https://<unique_id>.lhr.life/inbox │
╰───────────────┴─────────────────────────────────────────╯
Web interface available at: http://localhost:8000/
You then configure your developing application to send an activity to the Actor inbox or Shared inbox URI provided. When an activity arrives, fedify inbox only prints a summary table to your console indicating that a request was received:
╭────────────────┬─────────────────────────────────────╮
│ Request #: │ 2 │
├────────────────┼─────────────────────────────────────┤
│ Activity type: │ Follow │
├────────────────┼─────────────────────────────────────┤
│ HTTP request: │ POST /i/inbox │
├────────────────┼─────────────────────────────────────┤
│ HTTP response: │ 202 │
├────────────────┼─────────────────────────────────────┤
│ Details │ https://<unique_id>.lhr.life/r/2 │
╰────────────────┴─────────────────────────────────────╯
Crucially, the detailed information about the received request—including the full headers (like Signature), the request body (the Activity JSON), and the signature verification status—is only available in the web interface provided by fedify inbox. This web UI allows you to thoroughly inspect incoming activities during development.
When you need to test interactions with the live fediverse from your local machine beyond just sending, fedify tunnel can securely expose your entire local development server temporarily. This suite of tools significantly eases the process of building and debugging federated applications.
Implementing the ActivityPub suite of protocols from scratch is an incredibly complex and time-consuming undertaking. It involves deep dives into multiple technical specifications, cryptographic signing, security hardening, and navigating the nuances of a diverse ecosystem. While educational, it dramatically slows down the process of building the actual, unique features of your federated application.
Fedify offers a well-architected, secure, and type-safe foundation, handling the intricacies of federation for you—data modeling, discovery, core mechanics, delivery, security, and interoperability. It lets you focus on your application's unique value and user experience. Stop wrestling with low-level protocol details and start building your vision for the fediverse faster and more reliably. Give Fedify a try!
Getting started is straightforward. First, install the Fedify CLI using your preferred method. Once installed, create a new project template by running fedify init your-project-name.
Check out the Fedify tutorials and Fedify manual to learn more. Happy federating!
제가 직접 쓴 튜토리얼이긴 하지만, Fedify를 활용하는 〈나만의 연합우주 마이크로블로그 만들기〉도 꽤 괜찮은 자료라고 생각합니다. 😅
https://hackers.pub/@kodingwarrior/01962aef-a48f-7c09-bcd6-349cac256ca3
이걸 기준으로 팔로업하려는 참이었는데 감사합니다
https://socialhub.activitypub.rocks/t/guide-for-new-activitypub-implementers/479
액티비티펍 구현체 개발을 위한 가이드
작년에 진행하여 런칭한 프로젝트에서는 공공 데이터와 민간 플랫폼 데이터를 융합하고, 실시간 예측 모델과 시각화 대시보드, LLM 기반 질의응답 인터페이스까지 설계하며 데이터가 고객에게 실제로 활용 가능하도록 전달되는 구조를 고민했다. 데이터 PM으로서, 기술과 사용자 사이의 균형을 어떻게 만들고 복잡한 흐름을 어떻게 ‘보이게’ 만들 것인지에 집중했던 프로젝트 경험은 힘들지만 흥미로웠다. 그 때의 일을 간단히 글로 정리해보았습니다.
데이터가 서비스가 되려면, 또 다른 새로운 연결이 필요하다. 그리고 나는 데이터를 넘어, 더 넓은 맥락과 흐름을 설계하고 엮어내는 일의 재미와 의미를 알게 되었다. 그리고 이런 일도, 앞으로 더 많이, 잘 하게 될 일이라는 확신도 함께 얻었다.
단순히 슬라이드를 업로드하고 공유할 수만 있으면 충분한 것이긴 한데, PixelFed랑 비슷하게 접근을 해야하나
MVP 수준의 구현을 참고하려면 여기쯤이 최적인 것 같다 https://github.com/hackers-pub/hackerspub/tree/faf785e90ece8c78d29f276ba9ab1be8980c2ef7
해커스펍이 개발 초기에 어떤 모습이었는지 쭉 훑어보는 중.... MVP를 뽑을 수 있는 레벨로 가려면 대충 어느 쯤이어야하는지 감잡을 수 있을때까지 이분탐색하는 이 여정이 언제쯤에 끝날까....
단순히 슬라이드를 업로드하고 공유할 수만 있으면 충분한 것이긴 한데, PixelFed랑 비슷하게 접근을 해야하나
해커스펍이 개발 초기에 어떤 모습이었는지 쭉 훑어보는 중.... MVP를 뽑을 수 있는 레벨로 가려면 대충 어느 쯤이어야하는지 감잡을 수 있을때까지 이분탐색하는 이 여정이 언제쯤에 끝날까....
패디버스 앱으로서 해커스펍이 누릴 수 있는 기능 중 하나가 Remote Follow인데, 이건 다른 페디버스 앱에서도 마찬가지로 이런 기능이라는게 있다는걸 알지 못하는 경우가 많다. 새로 진입하는 분들 타겟으로 카드뉴스 같은거라도 만들어야 하나...... 라는 생각이 문득 들었다.
좋은 기능이 있어도 설명이 필요하다는 것 자체가 성공한 UX는 아닌 것 같은데, 이게 구조 상 어쩔 수 없이 생기는 문제인건가 싶기도 하고
개인적으로는 k8s쓰는 가장 큰 이유는 개발자 복지라고 생각한다. 적정기술만 쓰면 대부분의 사람들은 뭔가를 실 서비스에서 경험할 기회를 잃어버린다. 아니 이건 됐고…
온프레미스 클러스터 오퍼레이션 부담이나 EKS같은 서비스의 사용료 걱정만 없다면 쓰는게 무조건 낫다고 생각한다.
일단 k8s뿐만 아니라 컨테이너/머신 오케스트레이션의 세계에서 앱과 머신은 좀 더 잘 죽어도되는 존재가 된다. (물론 stateful한 호스트와 앱을 최대한 stateless하게 하거나, 상태를 분리하여 격리시켜야 하긴 한다)
그러면 docker-compose로 충분하지 않느냐 말할 사람도 있겠지만 처음에야 docker-compose 쓰는거나 k8s 쓰는거나 그게 그거지만(오히려 k8s가 성가실것이다) 마이그레이션의 때가 오면 난 그걸 감당할 자신이 없다.
물론 자신만의 가볍고 쏙 맘에드는 솔루션을 고집할 사람도 있을텐데… 난 남들이 다 쓰는거 쓰는게 편하다.