Native Shell
Native Shell은 모든 플랫폼의 앱 안에서 만들어지는 AI UI입니다
STL을 업로드해 중요 부분을 표시하고 배치 매트를 출력하면, 방문자는 QR코드 스캔으로 실물에 라벨을 확인합니다. 무료·오픈소스
Upload an STL, mark what matters and print one placement mat. Visitors scan its QR code and see labels on the real object, with no app to install. Free and open source.
개발 도구JavaScript · TypeScriptGitHub @Jin-hiroo온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Turn any 3D-printed object into an AR exhibit
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Turn any 3D-printed object into an AR exhibit: print a paper mat, scan a QR code, see labels on the real object.
Live app · Demo exhibit · Spec · Architecture · Contributing · Security
In AR: a 3D-printed skull on its printed mat, seen through a phone. The labels (1 左目 "left eye", 2 歯 "teeth") stay on the real object as the phone moves.
The same skull exhibit, left to right: its printable placement mat, its annotations in the Studio, and the visitor's view on a phone without AR (3D view with a label's details).
An exhibitor uploads an STL, marks points of interest and prints a paper placement mat with tracking markers. Visitors scan the QR code on the mat and see labels registered onto the real object, with no app to build and no object recognition to train.
/studio/<id>/calibrate), saved for every visitor.Requires Node 24+ and pnpm 10 (corepack enable picks the pinned version).
git clone https://github.com/Jin-hiroo/exhibitar.git && cd exhibitar && pnpm install
Sign-in and publishing need a Supabase project: copy .env.example to .env.local and fill it
in (see Self-hosting). Without it, everything else below still works.
pnpm dev # http://localhost:3000
/v/<id> page, which the QR code on the mat points to.The demo exhibit needs no backend: open http://localhost:3000/v/mockcube01 and print
/fixtures/mock-cube-mat.pdf to try it in AR. Add ?debug to any /v/<id> URL for the
tracking HUD. For the full product and data model, see docs/SPEC.md and
docs/ARCHITECTURE.md.
Contributor rules: CONTRIBUTING.md and CLAUDE.md. Workstreams: docs/TASKS.md.
| Command | What it does |
|---|---|
pnpm dev | local dev server on http://localhost:3000 |
pnpm lint && pnpm typecheck | ESLint + next typegen + tsc --noEmit |
pnpm test | Vitest unit tests (src/**/*.test.ts, tests/**/*.test.ts) |
pnpm test:e2e | Playwright smoke tests (starts its own dev server on :3100; with CI=1, serves the pnpm build output) |
pnpm fixtures | writes fixture STLs (binary + ASCII) to tests/fixtures/out/ |
pnpm demo | runs the full geometry + mat pipeline on every fixture → tests/fixtures/out/demo/ (GLB, mat SVG/PDF, marker PNGs, QR) |
pnpm mock | regenerates tests/fixtures/project.mock.json + public/fixtures/* from the real pipeline |
pnpm perf:nav [url] [runs] | times Studio page switches on any deployment (see below) |
pnpm perf:nav https://exhibitar.vercel.app clicks through the Studio and prints, per page
switch, the time until the next page shows, the server's share of it, and the region that
ran it. Set PERF_EMAIL and PERF_PASSWORD to measure signed-in pages too.nav → /path in DevTools → Performance → Timings.
Run localStorage.perf = '1' in the console to also log them as [perf] lines (always on in
pnpm dev). Studio responses carry a Server-Timing header (session check time, Vercel
region): DevTools → Network → a request → Timing.[perf] supabase … (Vercel →
Logs, or the pnpm dev terminal). PERF_LOG=1 logs every call.chrome://flags/#webxr-incubations.http://localhost:3000/fixtures/mock-cube-mat.pdf at Actual size (A4 landscape).pnpm dev, connect the phone by USB, adb reverse tcp:3000 tcp:3000.http://localhost:3000/v/mockcube01?debug → Start AR → point at the mat.Full checklist: docs/DEVICE-TESTS.md. Findings: docs/D0-FINDINGS.md.
WebXR only runs in a secure context. Three options, easiest first:
Android over USB (recommended for Android). Plain pnpm dev, then
forward the port so the phone sees it as localhost (a secure context):
adb reverse tcp:3000 tcp:3000
Open http://localhost:3000 in Chrome on the phone. Remote-debug via
chrome://inspect on the desktop.
Over Wi-Fi with a local certificate.
pnpm dev --experimental-https --hostname 0.0.0.0
Next.js generates a certificate with mkcert. The phone must trust the mkcert
root CA (mkcert -CAROOT → install rootCA.pem on the device), otherwise
WebXR will refuse the page. Browse to https://<your-LAN-IP>:3000.
Vercel preview deployment. Every pushed branch gets an HTTPS preview URL. Previews are behind Vercel Authentication, so sign in on the phone first (or use the production domain for public audience tests).
ExhibitAR is a Next.js app backed by a Supabase project (auth, Postgres, storage). Without Supabase env vars there is no sign-in, so the Studio works as an in-tab draft instead and the demo exhibit still loads; only saving and publishing are disabled.
supabase/migrations/ in file order,
either with the Supabase CLI (supabase link --project-ref <ref> then supabase db push)
or by pasting each file into the SQL editor. This creates the projects table, row-level
security, the viewer functions and the storage buckets./studio/account; people who signed in with Google don't have one there.https://<your-domain>; Redirect
URLs http://localhost:3000/** for local dev and, on Vercel,
https://<project>-*-<team>.vercel.app/** for previews. Google sign-in only returns to
the Site URL or an origin on this list..env.example): NEXT_PUBLIC_SUPABASE_URL,
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY and NEXT_PUBLIC_SITE_URL. The site URL is what
printed QR codes point at, so it must be your production domain.main deploys to production and branches get previews. Any host that runs Next.js works.
Run the server in the same region as your Supabase project: every Studio page queries it,
and each query across an ocean adds most of a second. vercel.json pins Vercel Functions
to hnd1 (Tokyo) for a Supabase project in ap-northeast-1; change it to match yours.ExhibitAR is licensed under the Apache License 2.0. See NOTICE.