OpenTUI: React, Bun, Zig로 터미널 앱 만들기

BBetter Stack
컴퓨터/소프트웨어AI/미래기술

Transcript

00:00:00OpenTui는 Zig 기반 라이브러리로, React, Solid, FreeJS 바인딩을 통해
00:00:04웹 애플리케이션을 만드는 것과 같은 방식으로 고성능 터미널 인터페이스를 구축할 수 있습니다.
00:00:09이 라이브러리는 유명한 오픈 소스 코딩 에이전트인 OpenCode를 개발한 Anomaly 팀에서
00:00:14수백만 명이 정기적으로 사용하는 OpenCode의 사용자 인터페이스를 구동하기 위해 만들었습니다.
00:00:19하지만 이 새로운 라이브러리는 기존의 인기 있는 React 터미널 인터페이스 도구와
00:00:24비교했을 때 어떤 점이 다를까요? 그 도구는 이미 오랫동안 사용되어 왔으며 많은
00:00:29코딩 에이전트를 구동하는 데 쓰이고 있습니다. 구독 버튼을 누르고 함께 알아봅시다!
00:00:35Ink는 React로 터미널 인터페이스를 만들 때 사용하는 대표적인 라이브러리입니다.
00:00:40여기에 대한 영상도 이미 만들었으니 확인해 보세요. 하지만 몇 가지 문제가 있습니다.
00:00:44우선 간단한 앱도 50MB 이상의 메모리를 사용하고 30fps로 고정되어 있는데,
00:00:51대부분의 애플리케이션에는 충분하지만, 코딩 에이전트처럼 텍스트를 많이
00:00:56스트리밍하는 앱을 만들 때는 프레임 제한 때문에 전체적으로 느리게 느껴집니다.
00:01:00그래서 원래 Golang과 Bubble Tea를 사용해 OpenCode를 만들었던 Anomaly 팀은
00:01:06Ink 없이 TypeScript로 다시 작성하기를 원했고, 그래서 OpenTui를 만들었습니다. 아니, 사실은
00:01:13처음부터 만든 건 아니고, 이미 Commander FX가 Zig 기반 터미널 라이브러리를
00:01:18개발 중이었기 때문에 Anomaly 팀이 그를 후원하고 그 기반 위에 OpenTui를 구축했습니다.
00:01:24Zig 코어가 모든 무거운 렌더링을 처리하고 TypeScript 바인딩을 통해 React나 Solid로 UI 컴포넌트를 작성할 수 있죠.
00:01:30가장 영리한 부분은 BUN의 외부 함수 인터페이스(FFI)인데, 이를 사용하면
00:01:36지연 시간 거의 없이 TypeScript에서 Zig 네이티브 코드로 직접 통신할 수 있어
00:01:42OpenTui가 매우 고성능입니다. Flexbox 레이아웃을 위해 Yoga를 사용하고,
00:01:47입력 창이나 선택 메뉴 같은 컴포넌트가 내장되어 있으며, 터미널 안에서 WebGPU 3D 그래픽을
00:01:54렌더링할 수 있는 3.js 패키지까지 있는데 정말 놀랍습니다. 간단한 데모로 직접 확인해 보죠.
00:01:59기본 OpenTui 프로젝트를 설정하는 방법은 많지만, 저는 BUN CreateTui를 쓰는 걸 좋아합니다.
00:02:04프로젝트 이름을 정하고 원하는 템플릿을 선택할 수 있는 아주 유용한 마법사가 제공되기 때문이죠.
00:02:09이제 React 템플릿을 선택할 건데, 세 템플릿의 차이점은 영상 뒤에서 설명해 드릴게요.
00:02:13완료되면 기본적인 전체 화면 프로젝트를 실행하는 index 파일들이 생성됩니다.
00:02:17코드를 살펴보면,
00:02:2115번째 줄에서 OpenTui의 렌더링 엔진을 사용하기 위해 CreateCLI 렌더러를 사용하고 있습니다.
00:02:27그 아래에는 앱 컴포넌트를 렌더링하는 CreateRoot가 있습니다. React에 익숙하다면
00:02:32이것이 HTML 파일에 마운트하는 코드라는 걸 아실 겁니다. 하지만 터미널에 렌더링하기 때문에
00:02:37이 프로젝트에는 index.html이 없고, 대신 터미널 박스와 텍스트를
00:02:42HTML 컴포넌트 대신 사용하는 커스텀 React 리컨실러(reconciler)를 사용합니다. 위쪽에는 박스 컴포넌트를 사용한 JSX가 있고,
00:02:49Yoga Flexbox 속성을 사용하여 내부 박스를 정렬하고 아스키 폰트와 기본적인 텍스트를 렌더링합니다.
00:02:55전체 화면 앱이 아니더라도 OpenTui는 여러 화면 모드를 지원합니다.
00:03:00footer height와 함께 split footer 모드로 변경하면 터미널 하단에 고정된 영역을 만들 수 있죠.
00:03:05단순히 화면 모드를 바꾸는 것보다 더 흥미로운 걸 해봅시다.
00:03:10여기에 타이틀 텍스트와 이름 입력 창이 있는 기본적인 TUI가 있습니다. 자, 이것 보세요. OpenTui를 쓰면
00:03:17반응형 디자인을 공짜로 얻을 수 있습니다. 터미널 너비가 바뀌어도 모든 게 잘 표시되죠. 그리고
00:03:21코드를 보면 매우 익숙한 React 문법을 사용하고 있습니다. 여기 useState로
00:03:26이름을 설정하고 있고, 입력창의 on input 속성에서 이름을 업데이트합니다. 그러면
00:03:32텍스트가 변경되는 거죠. OpenTui의 아주 멋진 기능은 HMR 없이 실시간으로 리로딩이 된다는 점입니다.
00:03:37여기서 텍스트를 'goodbye'로 바꾸고 파일을 저장하면 자동으로
00:03:43업데이트됩니다. 반응형 입력은 좋지만 가끔 텍스트가 안 보일 때가 있는데
00:03:48너비를 추가하면 훨씬 쉬워집니다. 박스 컴포넌트에는
00:03:52테두리나 배경색 같은 멋진 속성들이 있어 터미널 앱의 수준을 한 단계 높여줍니다.
00:03:56물론 텍스트 대신 아스키 폰트를 사용하여 제목을 더 돋보이게 할 수도 있습니다.
00:04:01물론 아스키 폰트는 여러 가지 선택할 수 있습니다. 기억하세요, 터미널
00:04:05앱이지 웹 페이지가 아니기 때문에 시스템에 있는 모든 폰트가 아닌 터미널이 지원하는 것만 렌더링합니다.
00:04:10보통의 React 앱처럼 상태를 변경하여 제출 시 뷰를 바꿀 수도 있습니다.
00:04:15조건에 따라 다른 JSX를 표시하는 방식이죠. 하지만 터미널에서 이런 게 될 거라고는
00:04:20예상치 못했을 겁니다. 이름을 제출하면, 다른 상태가 서서히 나타나죠.
00:04:25이건 OpenTui의 use timeline 훅을 사용해 애니메이션 지속 시간과 대상을 설정한 것입니다.
00:04:30컴포넌트의 불투명도(opacity)를 0으로, offset을 8로 설정했는데,
00:04:36즉 중앙 아래에 마진 탑이 있다는 뜻입니다. 여기 애니메이션은 offset 0과
00:04:40불투명도 1로 끝나게 설정되어 있습니다. 여기 설정된 값들을 업데이트해서 말이죠.
00:04:45터미널 애니메이션은 행 단위로 움직여야 해서 약간 끊겨 보일 수도 있지만,
00:04:50격자처럼 움직이는 거죠. 그래도 OpenTui로 이런 걸 쉽게 구현할 수 있다는 건 정말 멋집니다.
00:04:55지금까지 배운 것을 결합해 Flexbox 레이아웃으로 박스를 옆에 둘 수도 있습니다.
00:05:00한쪽에는 입력창을, 다른 쪽에는 박스를 두는 식으로요.
00:05:05그리고 입력창에 값을 넣고 제출하면, 그 값이 옆 박스로 이동하는 애니메이션을 넣을 수 있는데
00:05:10정말 괜찮은 기능이죠. OpenTui로는 이 외에도 정말 많은 것을 할 수 있습니다.
00:05:14use keyboard 훅으로 키보드 내비게이션을 활성화하거나, node OS로 시스템 데이터를 보여주거나,
00:05:19마우스 지원이나 가상화된 리스트를 쓸 수도 있습니다. 그리고 이 모든 게 BUN 위에서 돌아가므로
00:05:24BUN SQLite나 Postgres를 사용하거나 웹사이트처럼 외부 정보를 가져올 수도 있습니다.
00:05:28그리고 컴파일 후에는 용량이 71MB인데, 이는 BUN 런타임과 React 리컨실러가 포함되었기 때문입니다.
00:05:34하지만 앱을 실행하면
00:05:3950MB 이하의 메모리를 사용합니다. React는 워낙 유명해서
00:05:43LLM들이 너무나 잘 알고 있습니다. 그래서 문서만 왔다 갔다 할 필요 없이
00:05:49OpenTui로 매우 간단하게 앱을 만들 수 있습니다. OpenTui에 대한 아주 간단한
00:05:53훑어보기는 여기까지입니다. 아까 영상 초반에 약속했던
00:05:58React, Solid, Core의 차이점을 설명해 드리죠. 프론트엔드
00:06:02웹 개발을 안다면 매우 간단합니다. 기본적으로 모두 똑같은 Zig 코어를 통해 렌더링됩니다.
00:06:07즉 터미널에 그려지는 실제 과정은 거의 동일합니다. 차이점은 컴포넌트를
00:06:11어떻게 작성하고 업데이트를 어떻게 적용하느냐뿐입니다. React는 컴포넌트를 다시 실행하고 변경될 때마다
00:06:17가상 트리를 비교하는데, 이는 가상 DOM이 작동하는 방식과 매우 비슷합니다. Solid는 세밀하게 업데이트하므로
00:06:22변경된 부분만 업데이트합니다. 그리고 Core는 그 모든 과정을 건너뛰고
00:06:27객체를 직접 수정합니다. 이론상 React가 가장 무겁고 Core가 가장 가볍죠. 하지만 실제로는
00:06:33대부분의 터미널 앱에서 그 차이는 미미합니다. 모든 힘든 작업은 Zig 코어가 수행하기 때문입니다.
00:06:38즉, 이 경우 프레임워크는 개인적인 선호의 문제일 뿐입니다. 하지만 OpenTui 앱은
00:06:44BUN 런타임 전체와 특정 프레임워크 리컨실러를 포함하여 배포되더라도
00:06:50성능이나 앱 크기는 여전히 Ink보다 훨씬 작습니다. 물론 Ratatouille이나 Bubble Tea 같은
00:06:56네이티브 도구만큼 성능이 좋지는 않습니다. 하지만 제 생각에 JSX는 UI를 구성하는 가장 직관적이고
00:07:02최고의 방법입니다. 저는 크기나 메모리 효율성을 위해 업데이트가 힘들고 고생하는 것보다
00:07:09약간의 메모리와 크기 부담을 감수하더라도 개발 경험이 훨씬 좋은 TUI를 만드는 게 낫다고 생각합니다.
00:07:15그런 의미에서 저는 터미널 애플리케이션을 만든다면
00:07:20언제나 Ink 대신 OpenTui를 선택할 것입니다.
00:07:25조만간 만들기로 약속하죠.

Key Takeaway

OpenTui는 BUN의 FFI와 Zig 코어 렌더링을 활용하여, 기존 라이브러리의 성능 한계를 극복하고 익숙한 React 문법으로 고성능 터미널 인터페이스를 개발할 수 있는 효율적인 도구입니다.

Highlights

  • OpenTui는 Zig 코어 기반의 고성능 터미널 인터페이스 라이브러리로, BUN의 외부 함수 인터페이스(FFI)를 통해 TypeScript에서 네이티브 코드로 직접 통신하여 지연 시간을 최소화합니다.

  • 기존 React 기반 터미널 라이브러리인 Ink는 30fps 고정 프레임 제한과 50MB 이상의 메모리 사용 문제가 있지만, OpenTui는 이를 개선하여 고성능 터미널 앱을 구축할 수 있습니다.

  • OpenTui는 Yoga 레이아웃 엔진을 사용하여 복잡한 Flexbox 구조를 터미널 내에서 구현할 수 있으며, 실시간 코드 변경 사항이 HMR 없이 즉시 터미널에 반영됩니다.

  • 프로젝트 컴파일 시 BUN 런타임과 리컨실러를 포함하여 71MB 크기를 가지며, 실행 시 메모리 사용량은 50MB 이하로 유지됩니다.

  • React, Solid, Core 등 프레임워크 선택에 따라 업데이트 방식이 달라지지만, 무거운 작업은 Zig 코어가 처리하므로 실제 성능 차이는 미미합니다.

Timeline

OpenTui 개발 배경 및 기술적 차별점

  • OpenTui는 Anomaly 팀이 고성능 코딩 에이전트 OpenCode를 구동하기 위해 개발했습니다.
  • 기존 Ink 라이브러리의 30fps 프레임 제한과 높은 메모리 사용 문제를 해결하기 위해 Zig 기반으로 구축되었습니다.
  • BUN의 FFI를 사용하여 TypeScript에서 Zig 네이티브 코드로 직접 통신함으로써 지연 시간을 거의 없앴습니다.

기존의 인기 있는 React 터미널 인터페이스 라이브러리인 Ink는 텍스트 스트리밍이 많은 코딩 에이전트 환경에서 속도 저하를 겪었습니다. 이를 극복하고자 Zig 기반의 OpenTui가 도입되었습니다. 터미널 내에서 WebGPU 3D 렌더링까지 지원하며, Flexbox 레이아웃 엔진으로 Yoga를 채택했습니다.

OpenTui 프로젝트 설정 및 핵심 기능

  • BUN CreateTui 명령어를 통해 프로젝트 템플릿 선택과 초기 설정이 가능합니다.
  • HTML 대신 터미널 박스와 텍스트를 렌더링하는 커스텀 React 리컨실러를 사용합니다.
  • 터미널 너비 변화에 자동으로 대응하는 반응형 디자인과 파일 수정 시 즉각적인 실시간 리로딩을 지원합니다.

기본적인 전체 화면 프로젝트부터 분할 화면 모드까지 다양한 레이아웃을 지원합니다. Yoga 기반의 속성을 통해 박스 정렬, 테두리, 배경색 설정을 손쉽게 구현할 수 있습니다. 또한, use timeline 훅을 사용해 애니메이션 효과를 구현하거나, use keyboard 훅으로 키보드 내비게이션을 추가하는 등 풍부한 기능을 제공합니다.

프레임워크별 성능 분석 및 활용 전략

  • React는 컴포넌트 재실행 방식, Solid는 세밀한 업데이트, Core는 직접적인 객체 수정을 수행합니다.
  • 모든 무거운 렌더링 작업은 Zig 코어가 수행하므로 프레임워크 선택에 따른 성능 차이는 체감하기 어렵습니다.
  • 개발 생산성과 직관적인 JSX 문법을 고려할 때 Ink 대신 OpenTui를 사용하는 것이 합리적입니다.

프레임워크 간의 차이는 주로 컴포넌트 업데이트 방식에 있습니다. 이론적으로는 Core가 가장 가볍지만, 실제 앱 환경에서는 프레임워크의 선택보다 Zig 코어의 최적화가 더 큰 비중을 차지합니다. 결과적으로 메모리 효율성과 개발 경험을 모두 고려했을 때, Ink보다 우수한 대안으로 제시됩니다.

Community Posts

No posts yet. Be the first to write about this video!

Write about this video