Plain – 사람과 AI 에이전트 모두를 위해 설계된 Python 풀스택 웹 프레임워크
Show HN: Plain – The full-stack Python framework designed for humans and agents
TL;DR Highlight
Django를 포크해서 타입 명시, 단일 관습, 에이전트 친화적 구조로 재설계한 Python 웹 프레임워크로, LLM이 코드를 읽고 수정하기 쉽도록 만든 것이 핵심이다.
Who Should Read
LLM(Claude, Codex 등)을 활용한 바이브코딩이나 AI 에이전트 기반 개발을 시도 중인 Python 웹 개발자. 특히 Django의 복잡한 레거시에 불만을 느끼고 있는 개발자.
Core Mechanics
- Plain은 Django를 오랜 기간 실제 운영하면서 갈고닦은 포크로, Django의 핵심 구조는 유지하되 수년간 현장에서 발견한 불필요한 복잡성과 rough edge들을 정리한 프레임워크다.
- 가장 큰 특징은 Postgres 전용 모델 설계인데, 타입 어노테이션을 활용해 `email: str = types.EmailField()` 식으로 명시적으로 선언하는 방식이라 코드를 한 번만 읽어도 구조가 바로 파악된다.
- '인간에게 좋은 코드가 AI에게도 좋다'는 철학으로, 명시적(explicit), 타입 지정(typed), 예측 가능(predictable)한 코드 스타일을 채택해 LLM이 코드를 추론할 때 틀릴 확률을 줄인다.
- 시작 방법 자체가 에이전트 친화적이다. `claude "$(curl -sSf https://plainframework.com/start.md)"` 명령어 하나로 Claude 에이전트에게 프로젝트 셋업을 맡기거나, `uvx plain-start my-app`으로 직접 실행할 수 있다.
- plain-admin, plain-auth, plain-jobs, plain-oauth, plain-tailwind 등 풀스택에 필요한 패키지들이 모노레포 구조로 함께 제공되어, 에이전트가 선택지 없이 정해진 방식으로 기능을 붙일 수 있다.
- 각 모듈 내부에 상세한 README와 예제가 포함되어 있어, 에이전트가 외부 문서를 검색하지 않고도 코드베이스 안에서 컨텍스트를 얻을 수 있도록 설계되어 있다.
- Django의 Class-based View 대신 더 단순한 View 구조를 채택해, 에이전트가 상속 체계를 역추적하며 소스를 파고들 필요가 없게 만들었다.
- CLAUDE.md 파일이 레포 루트에 포함되어 있어 Claude 에이전트가 프로젝트 컨텍스트를 즉시 파악할 수 있도록 지원한다.
Evidence
- '에이전트를 위해 새로운 걸 만드는 건 역효과'라는 비판이 있었다. LLM의 훈련 데이터에 없는 새 프레임워크는 에이전트가 Django보다 못 쓸 수밖에 없다는 논리인데, 이에 대해 '에이전트는 마크다운 문서를 읽고 처음 보는 CLI도 정확히 호출했다, 중요한 건 훈련 데이터가 아니라 인터페이스가 예측 가능하냐는 것'이라는 반론이 나왔다.
- Django의 유연성이 오히려 에이전트에게 독이라는 의견이 공감을 얻었다. 'Django는 같은 걸 6가지 방법으로 할 수 있는데, Plain이 하나만 강제한다면 에이전트가 추론해야 할 표면적이 줄어드는 것이라 진짜 유용하다'는 분석이다.
- 'Django 코드베이스를 훔쳐서 이름만 바꾸고 AI 마케팅 붙인 것'이라는 신랄한 비판도 있었지만, 실제로 Plain을 오랫동안 지켜봐온 사용자들은 'vibe-coding이 유행하기 훨씬 전부터 개발해온 것이고, 설계 결정들이 탄탄하다'며 옹호했다.
- Class-based View 방식에 대한 비판이 있었다. 에이전트 친화적 프레임워크라고 하면서 간접 참조(indirection) 레이어가 있는 CBV를 쓰면, 에이전트가 기본 클래스를 반복해서 읽어야 해서 오히려 역효과라는 지적이다.
- 모델 선언 방식(타입 어노테이션 + 필드 할당)이 strawberry GraphQL 방식과 유사하다는 댓글이 있었고, 이 스타일이 개발 UX 측면에서 훨씬 낫다는 반응이 있었다. '규칙 기반 관습으로 리뷰할 코드 줄 수를 최소화하는 것이 에이전트 시대에 지속 가능한 프로젝트를 만드는 핵심'이라는 의견도 공감을 얻었다.
How to Apply
- Claude나 Codex 같은 AI 에이전트와 함께 새 프로젝트를 시작할 계획이라면, `mkdir my-app && cd my-app && claude "$(curl -sSf https://plainframework.com/start.md)"` 명령어로 에이전트에게 초기 셋업을 맡겨볼 수 있다. 에이전트가 plain-start 스크립트의 지시를 따라 프로젝트 구조를 자동으로 잡아준다.
- Django 기반 사이드 프로젝트를 AI 보조 코딩으로 빠르게 만들고 싶은 경우, Plain의 단일 관습 구조 덕분에 에이전트가 '어떤 방식으로 할지' 고민 없이 코드를 생성하고 인간이 리뷰할 코드 양도 줄어드는 효과를 얻을 수 있다.
- 기존 Django 프로젝트에서 에이전트 도입을 검토 중이라면, Plain 레포의 각 모듈별 README 구조와 CLAUDE.md 패턴을 참고해 기존 프로젝트에도 동일하게 에이전트용 컨텍스트 문서를 추가하는 방식을 먼저 적용해볼 수 있다.
- Postgres를 DB로 쓰는 신규 Python 웹앱을 만드는 팀이라면, `uvx plain-start my-app`으로 시작해 plain-admin, plain-auth, plain-jobs 같은 내장 패키지를 조합해 풀스택 앱을 빠르게 구성할 수 있다. 선택지가 하나로 고정되어 있어 팀 코드 리뷰 비용도 줄어든다.
Code Example
snippet
# 에이전트로 프로젝트 시작
mkdir my-app && cd my-app && claude "$(curl -sSf https://plainframework.com/start.md)"
# 또는 uv로 직접 시작
uvx plain-start my-app
# Plain의 모델 선언 방식 (타입 어노테이션 + 필드)
# app/users/models.py
from plain import postgres
from plain.postgres import types
from plain.postgres.functions import Now
from plain.passwords.models import PasswordField
@postgres.register_model
class User(postgres.Model):
email: str = types.EmailField()
password: str = PasswordField()
display_name: str = types.CharField(max_length=100)
is_admin: bool = types.BooleanField(default=False)
created_at: datetime = types.DateTimeField(default=Now)Terminology
vibe-coding명확한 설계 없이 AI에게 코드를 맡기며 감각적으로 빠르게 앱을 만드는 개발 방식. 생산성은 높지만 코드 품질 리뷰가 어렵다는 단점이 있다.
monorepository여러 패키지나 서브프로젝트를 하나의 Git 저장소에 모아 관리하는 방식. Plain은 plain-admin, plain-auth 등 수십 개의 패키지를 하나의 레포에서 관리한다.
Class-based ViewDjango에서 HTTP 요청 처리 로직을 클래스로 구조화하는 방식. 재사용성은 높지만 상속 체계가 복잡해 코드를 따라가기 어렵다는 단점이 있다.
opinionated framework특정 방식을 강제하는 프레임워크. 선택지가 줄어드는 대신 팀 전체가 동일한 패턴을 쓰게 되어 코드 일관성이 올라간다. Rails가 대표적인 예.
CLAUDE.mdClaude AI 에이전트가 프로젝트를 처음 열었을 때 참고하도록 만드는 컨텍스트 파일. 프로젝트 구조, 규칙, 주의사항 등을 담아두면 에이전트가 더 정확한 코드를 생성한다.