Community연구 & 데이터 분석github.com

PWA 앱 빌더

사용자의 프로젝트 아이디어만으로 프로덕션 준비가 완료된, 반응형이며 설치 가능한 PWA(React 18 + Vite + Tailwind 프론트엔드, Express 프로세스 하나, 내장 node:sqlite, 수제 서비스 워커, Web Push)를 구축합니다.

PWA 앱 빌더란 무엇인가요?

이 스킬은 사용자의 프로젝트 아이디어를 바탕으로 완전한 기능을 갖춘 프로그레시브 웹 앱(PWA)을 처음부터 구축하는 AI 비서입니다. 이는 사용자가 'PWA', 'React', 'API'와 같은 용어를 명시하지 않더라도 웹 앱, 대시보드, 트래커, 예약/주문/메모/습관/피트니스/비용 앱을 만들거나 'X를 위한 앱을 만들어 줘'라고 요청할 때 자동으로 활성화됩니다. 이 스킬은 제한된 호스트 환경(컴파일러 없음, 약 300MB RAM)에 맞게 조정된 고정 스택(React 18, Vite 5, Tailwind 3, Express 4, node:sqlite)을 사용합니다. 스킬은 8단계 프로세스로 구성되어 있습니다: 호스트 환경 점검, 사용자 요구사항 파악 및 인터뷰, 도메인 설계, 스캐폴딩, 데모 도메인을 실제 도메인으로 교체, RTL/LTR을 지원하는 프론트엔드 구축, PWA 및 푸시 알림 구현, 최종 검증 및 전달(공개 링크 포함). 또한 수제 서비스 워커, Web Push, 'useAlarmWatcher'를 통한 인앱 알림, HMAC 서명 쿠키 기반 세션 등 고유한 기능을 제공합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/AhmedAttia3/agent-skills/tree/HEAD/skills/pwa-app-builder

Installed? Explore more 연구 & 데이터 분석 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서


name: pwa-app-builder description: 프로덕션 준비가 완료된, 반응형이며 설치 가능한 PWA(React 18 + Vite + Tailwind 프론트엔드, Express 프로세스 하나, 내장 node:sqlite, 수제 서비스 워커, Web Push)를 사용자의 프로젝트 아이디어만으로 구축합니다. 사용자가 웹 앱, PWA, 모바일 설치형 웹 앱, 대시보드, 트래커, 포털, 예약/주문/메모/습관/피트니스/비용 스타일 앱을 만들거나, 빌드하거나, 부트스트랩하거나, 스캐폴딩해 달라고 요청하거나, "X를 위한 앱을 만들어 줘"라고 요청할 때 이 스킬을 사용하세요. 사용자가 "PWA", "React", "API"라는 단어를 전혀 언급하지 않더라도 마찬가지입니다. 또한 누군가 빈 작업 공간에서 새 앱을 원하면서 휴대폰에 설치, 푸시 알림, 오프라인 작업, 또는 공개 링크 공유를 언급할 때도 이 스킬을 사용하세요. license: MIT compatibility: Node.js 22.5 이상(node:sqlite용) 및 Python 3(아이콘 생성용). 기본 빌드 도구 체인, 데이터베이스 서버 또는 sudo 액세스가 필요하지 않습니다. 선택 사항: 공개 공유 링크용 cloudflared. metadata: author: Ahmed Attia version: 1.1.1

PWA 앱 빌더은(는) 무엇을 하나요?

프로젝트 아이디어를 첫날부터 실제로 작동하는 앱으로 바꾸십시오: 로컬에서 실행되고, 휴대폰에 설치 가능하며, 오프라인에서도 작동하고, 알림을 보내며, 공개 링크로 공유할 수 있습니다. 아래 스택은 의도적으로 고정되어 있습니다. 이것이 이러한 프로젝트가 실행되는 호스트 제약 조건(컴파일러 없음, ~300MB RAM, Postgres/MongoDB 없음, sudo 없음)에서 작동하는 유일한 조합입니다. 프로젝트마다 달라지는 것은 도메인입니다. 변하지 않는 것은 뼈대입니다.

무엇이든 하기 전에 이 전체 파일을 읽으십시오. 그런 다음 단계를 순서대로 진행하십시오. 각 단계에는 게이트가 있습니다.


0. 스택(변경 불가)

계층선택이유 (명백한 대안이 아닌 이유)
백엔드Express 4, CommonJS, 'use strict'하나의 프로세스가 API + 빌드된 UI + 이미지를 제공 → CORS 불필요, 재시작 항목 하나, 최저 메모리
데이터베이스node:sqlite (DatabaseSync)Node ≥22.5에 내장됨. 네이티브 모듈 제로. better-sqlite3는 설치조차 불가능(gcc 없음)
비밀번호crypto.scrypt + timingSafeEqualbcrypt 없음(네이티브). 절대 평문으로 저장하지 않음
세션HttpOnly 쿠키의 HMAC 서명된 토큰jsonwebtoken 의존성 없음, XSS에 localStorage 노출 없음
프론트엔드React 18 + Vite 5 + Tailwind 3, server/public으로 빌드빠른 저메모리 빌드, Express가 제공하는 정적 출력, SSR 불필요
PWA수제 sw.js + manifest.webmanifestWorkbox / vite-plugin-pwa 없음; 캐시 정책 완전 제어
푸시web-push + 로컬 생성 VAPID 키무료, Firebase 계정 불필요
이미지업로드 전에 Canvas로 브라우저에서 압축sharp/multer 없음(네이티브), 서버 RAM 절약
i18n작은 사내 사전, i18next 없음즉각적인 RTL/LTR 전환, 작은 번들

절대 추가하지 마세요: better-sqlite3, mongodb, pg, bcrypt, argon2, jsonwebtoken, sharp, canvas, multer, i18next, Workbox, vite-plugin-pwa, socket.io, 또는 네이티브 코드가 있는 모든 패키지. 만약 작업이 그러한 패키지를 필요로 하는 것처럼 보이면, 표준 라이브러리나 브라우저에서 해결하십시오.


1. 0단계 — 호스트 파악(먼저 수행)

bash <skill>/scripts/check-host.sh      # node, 컴파일러, RAM, 스왑, CPU, 포트, cloudflared

이 명령은 결과를 출력합니다. 계획에 반영해야 할 두 가지 사항:

  • 컴파일러 없음 → 위의 JS 전용 규칙은 선호도가 아니라 엄연한 사실입니다.
  • 낮은 리소스(⚠️ LOW RESOURCES) → npm install 및 npm run build는 로그 파일을 폴링하는 백그라운드에서 실행되어야 합니다. 포그라운드 장기 명령은 종료됩니다. references/host-constraints.md를 참조하십시오.

브라우저 규칙(중요하며, 조건부입니다)

기본적으로 curl과 API 스모크 테스트로 확인하는 것이 더 빠르고 저렴합니다. 하지만 규칙은 **"허가를 구하지 않고 브라우저를 실행하지 마라"**이지, "절대 실행하지 마라"가 아닙니다:

  • 쾌적한 호스트(≥4 CPU, 스왑 있음, 충분한 여유 RAM)에서: 허가를 구하는 것은 형식적인 절차입니다. 렌더링된 UI를 확인하기 위해 헤드리스 브라우저를 열고 싶다고 말하고 사용자가 결정하게 하십시오.

  • 저리소스 호스트(예: 2 vCPU / ~300MB / 스왑 없음)에서: 요청과 함께 그 이유를 미리 사용자에게 알리십시오. Chromium 인스턴스는 전체 머신을 소비하고, 서버가 OOM 킬(shutdown)되어 재시작이 필요할 수 있습니다. 다음과 같이 말하십시오:

    "UI를 시각적으로 확인하시겠습니까? 이 서버(2코어, 스왑 없음)에서 브라우저를 실행하면 리소스를 모두 소비하여 서버가 중단되고 재시작이 필요할 수 있습니다. 대신 curl과 API 테스트로 확인하시겠습니까, 아니면 제가 브라우저를 실행하기를 원하십니까?"

그런 다음 답변을 존중하십시오. 절대 브라우저를 조용히 실행하지 마십시오.


2. 1단계 — 아이디어 이해, 그리고 사용자 인터뷰(하드 게이트)

2a. 이해한 내용을 다시 설명 — 50줄이 아닌 5줄로

누가 사용하는지, 핵심 루프(가장 많이 반복하는 동작), 저장하는 데이터, 그리고 첫 번째 버전에서 "완료"가 무엇을 의미하는지 포함하십시오. 아직 아키텍처를 계획하지 마십시오.

2b. 빌드 전에 선호도 물어보기 — 필수이며 선택 사항이 아닙니다

사용자는 서비스 워커가 무엇인지 알기 훨씬 전에 보고 싶은 것이 무엇인지 알고 있습니다. 이러한 답변을 미리 얻는 것은 첫 번째 시도에 사용자가 좋아하는 앱과 세 번의 "색상 변경" 라운드의 차이를 만듭니다. system_ask_user 도구를 사용하여 사용자가 한 번의 탭으로 답변할 수 있게 하십시오 — 최대 5개의 질문, 각각 정확히 3개의 옵션. 빌드에 가장 큰 영향을 미치는 질문을 선택하십시오. 합리적으로 추론하거나 직접 결정할 수 있는 것은 건너뛰십시오.

질문 은행(프로젝트 도메인에 맞게 표현을 조정하고 사용자의 언어로 질문하십시오):

#질문옵션
1기본 인터페이스 언어한국어(RTL) + EN 전환 · 영어(LTR) + 한국어 전환 · 한국어만
2색상 아이덴티티따뜻한(주황/호박) · 차분한(청록/파랑) · 우아한(보라/남색) — 또는 프로젝트 도메인에 따라
3디자인 분위기심플하고 실용적이며 정보 중심 · 둥근 모서리와 애니메이션이 있는 현대적인 · 기본적으로 어둡고 세련된
4모바일 우선 또는 데스크톱 레이아웃하단 바가 있는 모바일 앱 · 사이드바가 있는 데스크톱 대시보드 · 둘 다(기본 반응형)
5계정가입 + 로그인 없는 게스트 모드 · 게스트 전용(나중에 업그레이드) · 계정 없음
6알림예약 알림 + 푸시 · 인앱 알림만 · 알림 없음
7공개 콘텐츠 준비JSON 파일에서 제공되는 콘텐츠 카탈로그 · 사용자 콘텐츠만 · 나중에
8이름 및 로고한국어 + 영어 이름과 이모지 · 하나의 이름과 그려진 아이콘 · 당신이 가장 좋은 것을 선택하세요

인터뷰 규칙: 절대 5개 이상 묻지 마십시오. 좋은 취향으로 결정할 수 있는 것(간격, 애니메이션 곡선)은 절대 묻지 마십시오. 사용자가 "당신이 선택하세요"라고 말하면 결정하고 넘어가십시오. 다시 묻지 마십시오. 답변을 기록하십시오. 이것은 3단계의 스캐폴드 플래그가 됩니다.

2c. 계획을 다시 알리고 기다리기

짧은 계획(스택은 이미 결정됨, 화면, 한 줄의 데이터 모델, 단계)을 제시하고 멈추십시오. 이 워크플로우의 대부분의 사용자는 코드가 작성되기 전에 승인하기를 원합니다. 한 줄의 "네, 시작하세요"는 빠르지만 잘못된 빌드보다 가치가 있습니다.


3. 2단계 — 도메인 설계(작고 구체적으로)

코드를 작성하기 전에 채팅에 다음을 작성하십시오:

  1. 엔티티 + 필드 — 사용자의 핵심 루프에 필요한 모든 필드; 필수 vs 선택 사항을 표시하십시오. 필수 필드를 최소한으로 유지하십시오(이름과 카테고리가 10개 필드 양식보다 낫습니다).
  2. 화면 — 나열하십시오; 각 화면은 web/src/pages/의 하나의 파일에 매핑됩니다.
  3. 라우트 — 엔티티당 하나의 REST 그룹 + 인증.
  4. 적용 가능한 선택적 모듈 — 계정/게스트, 알림+푸시, 공개 공유 링크, 공개 콘텐츠 카탈로그. 각각은 이미 템플릿에 구현되어 있습니다. 여러분은 발명하는 것이 아니라 선택하는 것입니다.

4. 3단계 — 스캐폴딩(하나의 명령어, 그다음 확인)

node <skill>/scripts/scaffold.mjs \
  --dir <workspace> --name "앱 이름" --name-en "AppName" \
  --slug appname --prefix ap --palette orange --ink warm [--with-catalog]

이 명령은 약 68개의 파일을 생성합니다: 완전한 작동 뼈대(인증, 하나의 데모 CRUD 엔터티, PWA 셸, 푸시, i18n, UI 키트, 운영 스크립트)와 앱 아이덴티티, 쿠키 접두사 및 브랜드 팔레트가 모든 곳에 이미 대체되어 있습니다. 팔레트: orange amber rose violet indigo sky teal emerald; 잉크: warm cool stone.

그런 다음, 다른 것을 건드리기 전에 — 파이프라인이 작동하는지 증명하십시오:

export PATH="$HOME/node-v24.20.0-linux-x64/bin:$PATH"   # Node는 이 호스트들의 PATH에 없습니다.
npm install            # 저RAM 호스트? 로그와 함께 백그라운드에서 실행하고 폴링하십시오.
npm run build
./scripts/run.sh start
curl -s http://127.0.0.1:3000/api/health
npm run test:api       # 신선한 데모 스캐폴드에서 "110 성공, 2 실패"를 예상합니다.

2개의 실패는 실제 이미지 파일이 필요한 카탈로그 어설션입니다(npm run catalog:images가 가져옴; 네트워크 필요). 도메인 변경을 시작하기 전에 다른 모든 것은 통과해야 합니다. 그렇지 않으면 나중에 실패가 자신의 것인지 알 수 없습니다.

references/templates-guide.md를 읽어 각 심어진 파일이 무엇인지와 교체하려는 데모 도메인 부분이 무엇인지 확인하십시오.


5. 4단계 — 데모 도메인을 실제 도메인으로 교체

스캐폴드는 완전한 작업 예제(식사 앱)를 제공하므로 정확히 그 형태를 복사할 수 있습니다. 데이터 계층에서 바깥쪽으로 작업하여 아무것도 매달리지 않도록 하십시오:

  1. server/db.js — 엔터티에 대한 데모 테이블을 다시 작성하십시오. 항상 추가적이어야 합니다: CREATE TABLE IF NOT EXISTS 블록의 새 테이블, 마이그레이션 배열에 추가된 새 열. 그런 다음 쿼리 함수를 작성하십시오.
  2. server/routes/<entity>.js — routes/meals.js를 표준 CRUD 라우터로 복사하십시오 (optionalFields, toEntity() 매퍼, INSERT/PATCH). server/index.js가 가져오는 방식과 일치하도록 내보내기 스타일을 맞추십시오(module.exports = router vs { router } — 리포지토리가 일관성이 없으므로 작성하기 전에 확인하십시오).
  3. server/index.js에 라우터를 마운트하십시오; 다른 것에는 API 접두사를 추가하지 마십시오(SPA 폴백은 이미 /api를 제외합니다).
  4. web/src/lib/api.js — 라우트당 하나의 메서드. 페이지나 컴포넌트에서 fetch를 절대 사용하지 마십시오.
  5. web/src/pages/* + web/src/App.jsx의 라우트.
  6. scripts/smoke-test.js — 기존 check(name, condition, extra) + call(path, {method, body}) 헬퍼를 사용하여 데모 어설션을 다시 작성하십시오. 이것이 증거입니다.

죽은 코드를 남기지 않도록 도메인에 필요하지 않은 것(데모 엔터티의 라우터, 페이지, API 메서드 및 i18n 키)을 삭제하십시오.


6. 5단계 — 프론트엔드: RTL 우선, 두 언어, 하나의 디자인 시스템

  • 모든 사용자 대상 문자열은 web/src/lib/i18n.js의 dict.ar와 dict.en 모두에 들어가고, t('key')로 읽히며, {name} 플레이스홀더를 통한 보간이 이루어집니다. 하나의 dict에만 키가 있으면 버그입니다.
  • 논리적 유틸리티(start-*/end-*/ps-*/pe-*/ms-*/me-*)를 사용하여 RTL과 LTR이 모두 작동하도록 하십시오. 의도적인 예외: 비밀번호 입력은 dir="ltr"이므로 실제 pr-12 / right-3를 사용합니다.
  • 흩어진 Tailwind를 작성하기 전에 web/src/styles.css의 컴포넌트 클래스(.card, .btn-primary, .input, .label, .chip)와 web/src/components/ui.jsx의 기본 요소를 재사용하십시오.
  • 테마는 documentElement의 클래스 기반이고, localStorage에 유지되며, 첫 번째 페인트 전에 web/index.html의 인라인 스크립트에 의해 적용됩니다(플래시를 없애고 iOS 상태 표시줄을 수정합니다).
  • 반응형: 하단 탐색이 있는 모바일 우선으로, md: 이상에서 사이드 레일이 됩니다(AppShell.jsx).
  • 다음에서 RTL/LTR을 확인하십시오: 양식, 목록, 앱 바, 모달 및 토스트 위치.

7. 6단계 — PWA + 알림

sw.js와 manifest.webmanifest가 심어져 있습니다. 잊지 말아야 할 두 가지:

  1. 해당 파일을 변경할 때마다 web/public/sw.js의 VERSION을 올리십시오. 그렇지 않으면 설치된 클라이언트가 오래된 캐시를 영원히 유지합니다.
  2. VAPID 키는 첫 번째 부팅 시 data/vapid.json에 생성됩니다. VAPID sub는 실제 확인 가능한 도메인이어야 합니다 (mailto:[email protected]) — Apple은 403 BadJwtToken과 함께 *.local/@localhost를 거부하는 반면 Google은 이를 허용하여 "Android에서는 작동하고 iPhone에서는 자동으로 실패"하는 고전적인 문제를 만듭니다. VAPID_SUBJECT로 재정의하십시오; 개인 주소를 하드코딩하지 마십시오.
  3. 공급자의 실제 응답 없이 푸시 성공을 보고하지 마십시오: sendToUser는 {total, sent, failed:[{status, reason}]}를 반환하고 죽은 구독(404/410/403)을 정리합니다.
  4. iOS는 앱이 홈 화면에 설치되어야 하고 탭에서 권한을 요청해야 합니다. 인앱 로컬 알림 폴백(App.jsx의 useAlarmWatcher)을 계속 작동하게 유지하십시오.

세부 정보 및 플랫폼 제한(알림 내 이미지, 상태 표시줄 색상, 독립 실행형 레터박싱)은 references/pwa-and-push.md에 있습니다. iOS에 대해 무엇이든 약속하기 전에 읽으십시오.


8. 7단계 — 확인(이것이 제공물의 증거입니다)

npm run test:api                                    # 격리된 data/test.db, 포트 3100, 실제 DB는 건드리지 않음
npm run build && ./scripts/run.sh restart
curl -s http://127.0.0.1:3000/api/health
curl -s http://127.0.0.1:3000/ | head -3            # 빌드된 SPA가 제공됨
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/manifest.webmanifest
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/sw.js

또한 curl로 실제 사용자 경로를 실행(등록/게스트 → 생성 → 읽기 → 업데이트 → 삭제)하여 "작동할 것"이 아닌 실제 출력을 보고할 수 있으십시오. 그런 다음 브라우저가 허용되면 휴대폰 크기의 뷰포트에서 시각적 통과를 위해 사용하십시오.

정확한 명령어와 실제 출력을 보고하십시오. 무언가 실패했다면 오류와 함께 말하십시오.


9. 8단계 — 전달

  1. 로컬 git 저장소 + 첫 번째 커밋(git init -b main), 그래야 위험한 실험 전에 돌아갈 수 있는 알려진 양호 상태가 있습니다. 요청하지 않는 한 절대 push하지 마십시오. 아랍어 제목의 Conventional Commits: feat(meals): دیدن فلتر الفئات.
  2. Cloudflare 빠른 터널을 통한 공개 링크(./scripts/tunnel.sh start, 그런 다음 tunnel.log에서 URL을 읽으십시오). 이 단계는 선택 사항이며 두 개의 별도 승인이 필요합니다:
    1. 공개 링크를 원하는지 물어보십시오. 이미 도메인, 리버스 프록시 또는 배포할 수 있는 호스팅을 소유하고 있다면 터널이 필요하지 않습니다. 터널을 강요하지 마십시오.
    2. 무엇이든 약속하기 전에 cloudflared를 확인하십시오(scripts/check-host.sh가 보고합니다). 없으면 설치 프로그램을 실행하기 전에 말하고 설치 허가를 요청하십시오. 절대 조용히 바이너리를 설치하지 마십시오. brew 또는 apt를 통해 설치를 제안하거나 Cloudflare의 바이너리 릴리스에서 직접 다운로드하십시오.
  3. 마지막 실행 상태:

    ✓ 88개 테스트 통과 - 0 실패 (AI가 생성한 스모크 테스트) ✓ 공개: https://some-id.trycloudflare.com ✓ 로컬: http://127.0.0.1:3000 ✓ 상태: git status는 깨끗함, 커밋 1개 ``` user@dev:~$ curl -s https://some-id.trycloudflare.com/api/health | head -1 {"status":"ok","version":"1.0.0"} ```

평가 기준(시도가 통과하려면 다음이 필요합니다):

  1. ✅ 스택 준수 — 네이티브 모듈이나 금지된 npm 패키지가 package.json 또는 node_modules에 없음.
  2. ✅ 작동하는 PWA — manifest.webmanifest 및 sw.js가 루트에서 제공되고, 서비스 워커가 설치됨.
  3. ✅ 작동하는 데이터베이스 — sk_test.db가 스모크 테스트 이후에 존재하고 비어 있지 않음.
  4. ✅ 작동하는 API — GET /api/health는 200과 유효한 JSON을 반환.
  5. ✅ 양방향 i18n — RTL 및 LTR 언어 모두 사용자에게 표시되어야 함.
  6. ✅ 테스트 통과 — npm run test:api는 ai_summary-smoke-test.js의 모든 주장을 통과해야 함.
  7. ✅ 자체 포함 — 프로젝트 디렉토리는 rm -rf node_modules && npm install && npm run build로 처음부터 다시 빌드 가능.

참조 파일

파일용도
references/host-constraints.md저리소스 호스트에서 npm 및 빌드 실행하기 위한 지침
references/pwa-and-push.md플랫폼별 PWA 한계, VAPID 문제 해결, iOS 요구 사항
references/templates-guide.md모든 심어진 파일의 전체 맵; 교체할 데모 부분 표시
references/end-to-end-testing.md스모크 테스트 및 API 테스트 작성 가이드

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

관련 스킬