DESIGN WORKBENCH 만들기: 초보자용 Chrome 확장앱 튜토리얼

좋은 디자인 도구 목록을 매일 쓰는 Chrome 사이드패널 확장앱으로 바꾸는 초보자용 실습 기록입니다. manifest.json, 사이드패널, 검색, 로컬 저장, zip 공유까지 단계별로 정리합니다.

이 문서는 좋은 레퍼런스 목록을 “나만의 작업 도구”로 바꾸는 과정을 설명합니다. 목표는 Chrome 웹스토어에 바로 올리는 것이 아니라, zip 파일을 나눠주고 각자 압축을 풀어 직접 설치해서 쓰게 만드는 것입니다.

0. 이 앱을 왜 만들었나

LinkedIn에 공유된 AI/프론트엔드 디자인 레퍼런스 모음처럼 좋은 목록은 발견에는 좋지만, 매일 쓰는 도구로는 한계가 있습니다.

목록의 한계:

  • 내가 지금 하려는 작업 기준으로 찾기 어렵다.
  • 자주 쓰는 도구와 처음 보는 도구가 같은 무게로 섞인다.
  • 메모, 즐겨찾기, 최근 사용, 작업별 묶음이 없다.
  • 브라우저 북마크에 넣으면 금방 흩어진다.

그래서 이 프로젝트는 목록을 그대로 복사하는 대신, 다음 질문에서 시작합니다.

“내가 오늘 디자인, 개발, 마케팅, 교육 작업을 시작할 때 바로 열고 싶은 도구는 무엇인가?”

Chrome 확장앱으로 만든 이유:

  • Chrome을 켜면 항상 쓸 수 있다.
  • 사이드패널로 열면 현재 작업 흐름을 방해하지 않는다.
  • 설치 서버가 없어도 된다.
  • 개인 데이터는 내 브라우저 안에 저장된다.
  • zip으로 압축해서 지인에게 쉽게 공유할 수 있다.

1. 완성 앱의 핵심 기능

초보자 과정에서는 기능을 전부 복잡하게 만들 필요가 없습니다. 아래 순서로 확장하면 됩니다.

  1. 도구 목록 보여주기
  2. 검색하기
  3. 카테고리/액션 필터 추가
  4. 카드 클릭 시 상세 보기
  5. 즐겨찾기, 메모, 최근 사용 저장
  6. 오늘 쓸 도구를 워크벤치에 담고 한 번에 열기
  7. zip으로 묶어서 공유

이 프로젝트의 현재 기능:

  • 4개 도메인: 교육, 개발자, 창작자, 마케팅
  • 태스크 프리셋
  • 퍼지 검색
  • Command Palette
  • 즐겨찾기, 메모, 컬렉션
  • 최근 사용, 클릭 횟수
  • 개인 워크벤치
  • 다크/라이트 테마
  • zip 빌드 스크립트

2. Chrome 확장앱 최소 구조

Chrome 확장앱은 특별한 서버가 없어도 동작합니다. 가장 중요한 파일은 manifest.json입니다.

가장 작은 구조:

1
2
3
4
5
6
7
8
9
10
my-extension/
├── manifest.json
├── sidepanel.html
├── app.js
├── styles.css
└── icons/
├── icon-16.png
├── icon-32.png
├── icon-48.png
└── icon-128.png

각 파일의 역할:

파일 역할
manifest.json 확장앱의 이름, 권한, 아이콘, 시작 파일을 Chrome에 알려준다.
sidepanel.html 사용자가 보는 화면의 뼈대다.
styles.css 색상, 간격, 카드, 버튼 같은 시각 디자인을 담당한다.
app.js 검색, 필터, 클릭, 저장 등 실제 동작을 담당한다.
icons/ Chrome 툴바와 확장 관리 화면에 보이는 아이콘이다.

이 프로젝트는 여기에 파일을 더 나눴습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DESIGN-WORKBENCH/
├── manifest.json
├── background.js
├── sidepanel.html
├── styles.css
├── app.js
├── data.js
├── data/
│ ├── education.js
│ ├── dev.js
│ ├── creator.js
│ └── marketing.js
├── search.js
├── palette.js
├── icons/
├── docs/
├── build.ps1
└── README.md

파일이 나뉜 이유:

  • data/*.js: 도구 목록이 길어지면 앱 로직과 분리해야 관리가 쉽다.
  • search.js: 검색 점수 계산만 따로 둔다.
  • palette.js: Command Palette 동작만 따로 둔다.
  • background.js: 확장 아이콘을 눌렀을 때 사이드패널을 여는 역할만 한다.
  • build.ps1: 공유용 zip을 만든다.

3. manifest.json 이해하기

현재 프로젝트의 핵심 설정은 이런 의미입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"manifest_version": 3,
"name": "Workbench — Creator·Dev·Marketing·Education",
"version": "3.0.0",
"description": "창작자 / 개발자 / 마케팅 / 교육 도구 워크벤치",
"action": {
"default_title": "Workbench 열기 (Alt+D)",
"default_icon": {
"16": "icons/icon-16.png",
"32": "icons/icon-32.png",
"48": "icons/icon-48.png",
"128": "icons/icon-128.png"
}
},
"side_panel": {
"default_path": "sidepanel.html"
},
"permissions": ["sidePanel", "storage", "tabs"],
"background": {
"service_worker": "background.js"
}
}

초보자가 꼭 알아야 하는 부분:

  • manifest_version: 3: 현재 Chrome 확장앱 표준입니다.
  • name: 확장앱 이름입니다.
  • version: zip을 새로 만들 때 버전을 올리면 관리하기 쉽습니다.
  • action: 툴바 아이콘과 제목입니다.
  • side_panel.default_path: 사이드패널에서 열 HTML입니다.
  • permissions: 앱이 쓸 수 있는 Chrome 기능입니다.

권한 설명:

권한 왜 필요한가
sidePanel Chrome 사이드패널을 열기 위해 필요합니다.
storage 즐겨찾기, 메모, 최근 사용을 저장하기 위해 필요합니다.
tabs 워크벤치에 담은 도구를 새 탭으로 열기 위해 필요합니다.

초보자에게 중요한 원칙:

권한은 필요한 만큼만 넣는다. 일단 넓게 넣고 나중에 줄이는 방식은 피한다.

4. 데이터를 어떻게 설계할까

처음에는 도구를 배열로 만들면 충분합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
export const TOOLS = [
{
id: 'react-bits',
name: 'React Bits',
url: 'https://reactbits.dev',
domain: 'reactbits.dev',
desc: '고품질 애니메이션 React 컴포넌트 모음.',
action: 'Use',
categories: ['component', 'animation'],
tags: ['react', 'open-source'],
featured: true
}
];

필드별 의미:

필드 설명
id 코드에서 도구를 구분하는 고유 이름입니다. 영문 소문자와 -를 추천합니다.
name 화면에 표시할 이름입니다.
url 클릭하면 열 주소입니다.
domain 카드에 짧게 보여줄 도메인입니다.
desc 검색과 상세 화면에 쓰는 설명입니다.
action Use, Build, Explore, Learn, Read, Watch 같은 사용 목적입니다.
categories 큰 분류입니다. 한 도구가 여러 카테고리에 들어갈 수 있습니다.
tags 검색을 돕는 작은 키워드입니다.
featured 처음 화면에서 우선 보여줄 도구입니다.

좋은 데이터 작성법:

  • 이름보다 “언제 쓰는 도구인지”를 설명에 적습니다.
  • 태그는 3~5개 정도만 넣습니다.
  • 카테고리는 너무 많이 만들지 않습니다.
  • URL은 실제로 열리는지 확인합니다.

5. UI는 어떻게 구성할까

초보자 버전의 sidepanel.html은 이런 구성이면 충분합니다.

1
2
3
4
5
6
7
8
9
<header>
<h1>Design Workbench</h1>
</header>

<input id="search" type="search" placeholder="도구 검색..." />

<section id="presets"></section>
<section id="filters"></section>
<main id="tools-list"></main>

이 프로젝트의 실제 UI 구성:

1
2
3
4
5
6
7
8
9
10
11
Header
Search
Personal Workbench
Task Presets
Collections
Filters
Result Bar
Tools List
Detail Drawer
Command Palette
Help Overlay

처음부터 전부 만들 필요는 없습니다. 추천 순서는 다음과 같습니다.

  1. tools-list에 카드 렌더링
  2. 검색 input 연결
  3. 필터 버튼 연결
  4. 카드 클릭 시 drawer 열기
  5. 즐겨찾기 저장
  6. 워크벤치 큐 추가

6. 저장은 어떻게 하나

Chrome 확장앱에서는 chrome.storage.local을 사용합니다.

예시:

1
2
3
4
5
chrome.storage.local.set({ favorites: ['react-bits'] });

chrome.storage.local.get(['favorites'], (result) => {
console.log(result.favorites);
});

이 프로젝트는 브라우저에서 직접 HTML을 열어도 테스트할 수 있도록 localStorage 폴백을 둡니다.

1
2
3
4
5
6
7
8
const storage = {
async get(key) {
if (typeof chrome !== 'undefined' && chrome.storage?.local) {
return new Promise((res) => chrome.storage.local.get([key], (r) => res(r[key])));
}
return JSON.parse(localStorage.getItem(key) || 'null');
}
};

이렇게 하면:

  • 확장앱으로 설치하면 chrome.storage.local에 저장됩니다.
  • 그냥 sidepanel.html을 열면 localStorage에 저장됩니다.

초보자에게는 이 방식이 디버깅하기 쉽습니다.

7. 설치 방법: 초보자용

개발자 본인이 설치할 때:

  1. Chrome 주소창에 chrome://extensions 입력
  2. 오른쪽 위 개발자 모드 켜기
  3. 압축해제된 확장 프로그램을 로드합니다 클릭
  4. 프로젝트 폴더 선택
  5. 툴바 아이콘 클릭 또는 Alt+D

수정 후 반영:

  1. 파일 수정
  2. chrome://extensions로 이동
  3. 해당 확장앱의 새로고침 버튼 클릭
  4. 다시 열기

8. zip으로 나눠주는 방법

웹스토어에 올리지 않고 지인에게 나눠줄 때는 zip 방식이 가장 쉽습니다.

개발자가 할 일:

1
.\build.ps1

그러면 보통 이런 파일이 생깁니다.

1
dist/workbench-v3.0.0.zip

받는 사람이 할 일:

  1. zip 파일을 다운로드합니다.
  2. 압축을 풉니다.
  3. Chrome에서 chrome://extensions를 엽니다.
  4. 개발자 모드를 켭니다.
  5. 압축해제된 확장 프로그램을 로드합니다를 누릅니다.
  6. 압축을 푼 폴더를 선택합니다.

주의:

  • zip 파일 자체를 Chrome에 넣는 것이 아닙니다.
  • 반드시 압축을 먼저 풀고, 그 폴더를 선택해야 합니다.
  • 폴더를 삭제하면 확장앱도 더 이상 정상 동작하지 않습니다.

9. 공유용 zip에 들어가야 하는 파일

zip에는 실행에 필요한 파일만 넣는 것이 좋습니다.

필수:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
manifest.json
background.js
sidepanel.html
styles.css
app.js
data.js
palette.js
search.js
data/*.js
icons/icon-16.png
icons/icon-32.png
icons/icon-48.png
icons/icon-128.png
README.md

넣지 않아도 되는 것:

1
2
3
4
5
6
7
docs/
dist/
build.ps1
rename-brand.ps1
icons/icon-master.png
icons/icon-256.png
icons/icon-512.png

build.ps1은 이 구분을 자동으로 처리합니다.

10. 초보자가 따라 만들 수 있는 1일차 과제

처음부터 현재 앱 전체를 만들려고 하면 어렵습니다. 아래 범위만 만들면 충분합니다.

1일차 목표:

  • 확장앱 이름 정하기
  • manifest.json 만들기
  • sidepanel.html 만들기
  • 도구 카드 5개 보여주기
  • 검색 input으로 이름 필터링하기
  • Chrome에 unpacked extension으로 설치하기

추천 파일 구조:

1
2
3
4
5
6
7
my-first-workbench/
├── manifest.json
├── sidepanel.html
├── app.js
├── styles.css
└── icons/
└── icon-128.png

최소 manifest.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"manifest_version": 3,
"name": "My First Workbench",
"version": "0.1.0",
"description": "내가 자주 쓰는 도구 모음",
"action": {
"default_title": "Open Workbench"
},
"side_panel": {
"default_path": "sidepanel.html"
},
"permissions": ["sidePanel"],
"background": {
"service_worker": "background.js"
}
}

최소 background.js:

1
2
3
chrome.sidePanel
.setPanelBehavior({ openPanelOnActionClick: true })
.catch(console.error);

최소 sidepanel.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Workbench</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header>
<h1>My Workbench</h1>
</header>
<input id="search" type="search" placeholder="검색..." />
<main id="tools"></main>
<script type="module" src="app.js"></script>
</body>
</html>

최소 app.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const tools = [
{
name: 'React Bits',
url: 'https://reactbits.dev',
desc: 'React 컴포넌트와 애니메이션 레퍼런스'
},
{
name: '21st.dev',
url: 'https://21st.dev',
desc: 'AI 시대 UI 컴포넌트 마켓플레이스'
}
];

const search = document.querySelector('#search');
const list = document.querySelector('#tools');

function render(items) {
list.innerHTML = items.map((tool) => `
<article class="card">
<h2>${tool.name}</h2>
<p>${tool.desc}</p>
<button data-url="${tool.url}">열기</button>
</article>
`).join('');
}

search.addEventListener('input', () => {
const q = search.value.toLowerCase();
render(tools.filter((tool) => tool.name.toLowerCase().includes(q)));
});

list.addEventListener('click', (event) => {
const button = event.target.closest('button[data-url]');
if (!button) return;
chrome.tabs.create({ url: button.dataset.url });
});

render(tools);

최소 styles.css:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
body {
margin: 0;
padding: 16px;
font-family: system-ui, sans-serif;
background: #101010;
color: #f5f5f5;
}

input {
width: 100%;
height: 36px;
margin: 12px 0;
}

.card {
padding: 12px;
margin-bottom: 8px;
border: 1px solid #333;
border-radius: 8px;
background: #181818;
}

중요: 위 app.jschrome.tabs.create를 쓰므로 manifest.jsonpermissionstabs를 추가해야 합니다.

1
"permissions": ["sidePanel", "tabs"]

11. 중급 과정에서 추가할 기능

기본 목록 앱이 되면 다음 기능을 하나씩 추가합니다.

  1. data.js로 도구 목록 분리
  2. 카테고리 필터
  3. 즐겨찾기 저장
  4. 최근 사용 저장
  5. 상세 drawer
  6. 워크벤치 큐
  7. Command Palette
  8. export/import
  9. 아이콘 제작
  10. zip 빌드 자동화

학습 순서는 “보이는 것 → 클릭되는 것 → 저장되는 것 → 공유되는 것”이 좋습니다.

12. 고급 과정: Chrome 웹스토어 등록

기초 과정에서는 웹스토어 등록을 다루지 않아도 됩니다. zip 공유만으로 충분합니다.

실제 등록을 다룰 때는 후속 글인 고급 과정: Chrome Web Store 등록하기를 사용합니다. 이 문서는 로컬의 Chrome Web Store 제출 스킬 자료와 현재 프로젝트의 docs/store-listing.md, docs/privacy.md를 바탕으로 작성되어 있습니다.

고급 과정에서 다룰 내용:

  • Chrome Web Store 개발자 계정 등록
  • 개인정보처리방침 작성
  • 권한 사용 사유 정리
  • 스크린샷과 설명문 작성
  • 원격 코드 금지 정책 확인
  • 심사용 테스트 계정/테스트 절차 작성
  • 버전 업데이트와 재심사 대응

웹스토어 제출 전에 확인할 것:

  • manifest_version이 3인지
  • 권한이 최소한인지
  • manifest.json에 없는 파일을 참조하지 않는지
  • 외부 스크립트를 실행하지 않는지
  • 개인정보를 서버로 보내지 않는지
  • README와 privacy 문서가 실제 동작과 맞는지

13. 튜토리얼을 가르칠 때 추천 흐름

수업 흐름 예시:

  1. 좋은 레퍼런스 목록을 보여준다.
  2. “목록은 왜 매일 쓰기 어려울까?”를 같이 이야기한다.
  3. 내가 자주 쓰는 도구 10개를 고르게 한다.
  4. 도구마다 name, url, desc, tags를 적게 한다.
  5. 최소 확장앱을 만든다.
  6. Chrome에서 unpacked extension으로 설치한다.
  7. 검색 기능을 추가한다.
  8. 즐겨찾기나 워크벤치 중 하나를 추가한다.
  9. zip으로 묶어 옆 사람에게 설치시킨다.
  10. 마지막에 “웹스토어 등록은 고급 과정”이라고 분리한다.

이렇게 하면 초보자도 “확장앱 개발”을 거창한 배포 프로젝트가 아니라, 자기 문제를 해결하는 작은 도구 제작으로 이해할 수 있습니다.

14. 이 프로젝트에서 계속 발전시킬 아이디어

다음 단계로 발전시키기 좋은 기능:

  • 사용자가 CSV로 도구 목록을 가져오기
  • 팀별 추천 프리셋 만들기
  • 도구별 스크린샷 썸네일 추가
  • 즐겨찾기/메모 백업 파일 자동 이름 개선
  • 공유용 zip 안에 설치 안내 HTML 포함
  • 웹스토어 제출용 스크린샷 자동 생성

핵심은 기능을 많이 넣는 것이 아니라, 매일 열고 싶은 흐름을 만드는 것입니다.

Comments

댓글

GitHub 계정으로 의견을 남길 수 있습니다. 댓글은 GitHub Discussions에 저장됩니다.