-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbookmarks-export.html
More file actions
275 lines (264 loc) · 28.5 KB
/
Copy pathbookmarks-export.html
File metadata and controls
275 lines (264 loc) · 28.5 KB
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
<!doctype html>
<!-- Generated by scripts/site.mjs from scripts/site-content.mjs. Edit those, not this file. -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<title>Export your X (Twitter) bookmarks, free · x-utils</title>
<meta name="description" content="Free bookmarks export for X (Twitter): every bookmarked post as a readable page with media and numbers, a Markdown file for your notes app and a CSV. No API, no password.">
<link rel="canonical" href="https://x-utils.com/bookmarks-export">
<meta property="og:title" content="Export your X (Twitter) bookmarks, free">
<meta property="og:description" content="Free bookmarks export for X (Twitter): every bookmarked post as a readable page with media and numbers, a Markdown file for your notes app and a CSV. No API, no password.">
<meta property="og:image" content="https://x-utils.com/docs/assets/report-bookmarks.png">
<meta property="og:url" content="https://x-utils.com/bookmarks-export">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@devploit">
<meta name="twitter:creator" content="@devploit">
<meta name="twitter:title" content="Export your X (Twitter) bookmarks, free">
<meta name="twitter:description" content="Free bookmarks export for X (Twitter): every bookmarked post as a readable page with media and numbers, a Markdown file for your notes app and a CSV. No API, no password.">
<meta name="twitter:image" content="https://x-utils.com/docs/assets/report-bookmarks.png">
<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Crect%20width%3D%2232%22%20height%3D%2232%22%20rx%3D%227%22%20fill%3D%22%230d1220%22%2F%3E%3Cpath%20d%3D%22M8%208l16%2016M24%208L8%2024%22%20stroke%3D%22%23b3a6ff%22%20stroke-width%3D%224%22%20stroke-linecap%3D%22round%22%2F%3E%3C%2Fsvg%3E">
<script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"x-utils","item":"https://x-utils.com/"},{"@type":"ListItem","position":2,"name":"Export your X (Twitter) bookmarks","item":"https://x-utils.com/bookmarks-export"}]}</script>
<script type="application/ld+json">{"@context":"https://schema.org","@type":"HowTo","name":"Export your X (Twitter) bookmarks, free","description":"Free bookmarks export for X (Twitter): every bookmarked post as a readable page with media and numbers, a Markdown file for your notes app and a CSV. No API, no password.","totalTime":"PT5M","tool":{"@type":"HowToTool","name":"A desktop browser"},"step":[{"@type":"HowToStep","position":1,"name":"Open your bookmarks page on X","text":"On a computer, log in to X and open x.com/i/history. If the page was already open, reload it right before pasting: the tool reads the list as X loads it."},{"@type":"HowToStep","position":2,"name":"Open the browser console","text":"Press Cmd+Option+I on a Mac or F12 on Windows and Linux, then click the Console tab."},{"@type":"HowToStep","position":3,"name":"Copy the script","text":"Use the copy button on this page. The script is plain text you can read; it lives at x-utils.com/dist/bookmarks-export.js."},{"@type":"HowToStep","position":4,"name":"Paste it in the console and press Enter","text":"The first time, the browser asks you to type \"allow pasting\" first. Type it, press Enter, paste again."},{"@type":"HowToStep","position":5,"name":"Wait, then open your report","text":"About a minute per few hundred bookmarks. The report and a CSV land in your Downloads folder."}]}</script>
<script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"My bookmarks are at a different address","acceptedAnswer":{"@type":"Answer","text":"X moved bookmarks to x.com/i/history in 2026. Both that page and the old x.com/i/bookmarks work with the tool."}},{"@type":"Question","name":"Are images downloaded?","acceptedAnswer":{"@type":"Answer","text":"The report links to the images on X's servers and shows thumbnails. The files themselves are not copied."}}]}</script>
<style>
:root{--band:#0d1220;--band-2:#161d33;--band-ink:#f4f6fb;--band-muted:#8f9ab3;--ground:#eef0f4;--surface:#fff;--surface-2:#f6f7fa;--ink:#0d1220;--muted:#66708a;--line:#e3e6ee;--accent:#5b3df5;--accent-soft:rgba(91,61,245,.12);--good:#12805c;--good-soft:rgba(18,128,92,.12);--bad:#d2481d;--warn:#a86b0f;--warn-soft:rgba(168,107,15,.14);--mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;--sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,Helvetica,Arial,sans-serif;--shadow:0 1px 2px rgba(13,18,32,.06),0 12px 32px -16px rgba(13,18,32,.18)}
@media (prefers-color-scheme:dark){:root{--band:#080b14;--band-2:#0f1424;--ground:#0b0f19;--surface:#121826;--surface-2:#171e2e;--ink:#e8ecf5;--muted:#8d97ad;--line:#222b3d;--accent:#a394ff;--accent-soft:rgba(163,148,255,.16);--good:#4fd39b;--good-soft:rgba(79,211,155,.14);--bad:#ff9a6c;--warn:#e2b35c;--warn-soft:rgba(226,179,92,.16);--shadow:0 1px 2px rgba(0,0,0,.4),0 16px 40px -20px rgba(0,0,0,.8)}}
*{box-sizing:border-box}html{scroll-behavior:smooth}@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;background:var(--ground);color:var(--ink);font:16px/1.55 var(--sans);-webkit-font-smoothing:antialiased}
a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
svg{width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;vertical-align:-.15em}
.wrap{max-width:1120px;margin:0 auto;padding:0 28px}
.mono{font-family:var(--mono)}
kbd{font:500 12.5px var(--mono);padding:2px 7px;border:1px solid var(--line);border-bottom-width:2px;border-radius:6px;background:var(--surface-2);color:var(--ink);white-space:nowrap}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
/* masthead */
.band{background:radial-gradient(900px 360px at 12% -20%,rgba(120,96,255,.35),transparent 65%),radial-gradient(700px 300px at 95% 10%,rgba(46,196,182,.18),transparent 60%),linear-gradient(180deg,var(--band-2),var(--band));color:var(--band-ink);padding:28px 0 72px}
.nav{display:flex;justify-content:space-between;align-items:center;gap:16px;color:var(--band-muted)}
.nav .brand{display:inline-flex;align-items:center;gap:10px;color:var(--band-ink);font:700 18px/1 var(--sans);letter-spacing:-.02em;text-decoration:none!important}
.nav .brand i{width:14px;height:14px;border-radius:4px;background:linear-gradient(135deg,#b3a6ff,#5ee0a8)}
.nav .brand:hover{color:#b3a6ff}
.nav .links{display:flex;align-items:center;gap:4px;font:500 13.5px var(--sans)}
.nav .links a{color:var(--band-muted);padding:7px 11px;border-radius:8px;text-decoration:none}
.nav .links a:hover{color:var(--band-ink);background:rgba(255,255,255,.06)}
.nav .links a.active{color:var(--band-ink);background:rgba(255,255,255,.08)}
.nav .links a.go{background:#b3a6ff;color:#0d1220;font-weight:650;margin-left:6px}.nav .links a.go:hover{background:#c4baff}
.hero{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;align-items:end;padding:56px 0 0}
.hero h1{margin:0 0 16px;font-size:clamp(34px,4.6vw,56px);font-weight:750;letter-spacing:-.035em;line-height:1.02;text-wrap:balance}
.hero p{margin:0 0 22px;font-size:18px;color:var(--band-muted);max-width:52ch}
.pills{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:26px}
.pill{display:inline-flex;align-items:center;gap:6px;font:500 12.5px var(--mono);padding:5px 10px;border-radius:999px;border:1px solid rgba(255,255,255,.14);color:#c7cede}
.pill svg{color:#5ee0a8}
.cta{display:inline-flex;align-items:center;gap:8px;height:46px;padding:0 18px;border-radius:10px;background:#b3a6ff;color:#0d1220;font-weight:650;text-decoration:none!important}
.cta:hover{background:#c4baff}
.cta.quiet{background:rgba(255,255,255,.08);color:var(--band-ink);margin-left:8px}
.hero-shot{position:relative;border-radius:14px;overflow:hidden;box-shadow:0 30px 80px -30px rgba(0,0,0,.8);border:1px solid rgba(255,255,255,.1);transform:translateY(104px)}
.hero-shot img{display:block;width:100%;height:auto}
/* content */
.content{padding:96px 0 64px}
h2{font-size:28px;letter-spacing:-.02em;margin:0 0 6px}
h3{font-size:18px;letter-spacing:-.01em;margin:0 0 8px}
.lead{color:var(--muted);margin:0 0 24px;max-width:70ch;font-size:16.5px}
section{margin-bottom:72px}
.card{background:var(--surface);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow)}
/* three-beat explanation */
.beats{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px}
.beat{padding:20px 22px}
.beat .ic{display:inline-grid;place-items:center;width:38px;height:38px;border-radius:10px;background:var(--accent-soft);color:var(--accent);font-size:18px;margin-bottom:12px}
.beat p{margin:0;color:var(--muted);font-size:15px}
/* guided setup */
.guide{padding:0;overflow:hidden}
.guide-head{padding:22px 24px 18px;border-bottom:1px solid var(--line);display:flex;flex-wrap:wrap;gap:16px 28px;align-items:flex-start}
.field{display:flex;flex-direction:column;gap:6px;min-width:220px;flex:1}
.field label{font-size:13px;font-weight:600;color:var(--muted)}
.field select,.field .inp{font:inherit;height:44px;padding:0 12px;border:1px solid var(--line);border-radius:10px;background:var(--surface-2);color:var(--ink);width:100%}
.field .inp{display:flex;align-items:center;gap:4px;padding:0 12px}
.field .inp span{color:var(--muted);font-family:var(--mono);font-size:14px}
.field .inp input{border:0;background:transparent;font:inherit;color:var(--ink);width:100%;outline:none;font-family:var(--mono)}
.field:focus-within select,.field:focus-within .inp{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.field .hint{font-size:12.5px;color:var(--muted)}
.gsteps{counter-reset:g}
.gstep{display:grid;grid-template-columns:56px minmax(0,1fr);gap:0 18px;padding:22px 24px;border-bottom:1px solid var(--line)}
.gstep.has-aside{grid-template-columns:56px minmax(0,1fr) minmax(0,460px)}
.gstep .aside{grid-column:3;align-self:start}
.gstep .aside .mock,.gstep .aside .panel-mock{margin-top:0}
.gstep:last-child{border-bottom:0}
.gstep::before{counter-increment:g;content:counter(g);display:grid;place-items:center;width:40px;height:40px;border-radius:12px;background:var(--ink);color:var(--surface);font:700 16px var(--mono)}
.gstep h3{margin:6px 0 6px}
.gstep p{margin:0 0 12px;color:var(--muted);font-size:15.5px;max-width:64ch}
.gstep p:last-child{margin-bottom:0}
.gstep .row{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.btn{display:inline-flex;align-items:center;gap:8px;height:42px;padding:0 16px;border-radius:10px;border:1px solid var(--line);background:var(--surface);color:var(--ink);font:600 15px var(--sans);cursor:pointer;text-decoration:none!important;white-space:nowrap}
.btn:hover{background:var(--surface-2)}.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}.btn.primary:hover{filter:brightness(.94)}.btn.done{border-color:var(--good);color:var(--good);background:var(--good-soft)}
.btn.sm{height:34px;padding:0 12px;font-size:13.5px;font-weight:500}
.btn.use{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 40%,var(--line));background:var(--surface)}.btn.use:hover{background:var(--accent-soft)}
.tool.featured .btn.use{background:var(--accent);border-color:var(--accent);color:#fff}
.urlbox{display:inline-flex;align-items:center;gap:0;font:14px var(--mono);padding:10px 14px;border-radius:10px;background:var(--surface-2);border:1px solid var(--line);color:var(--ink);word-break:break-all}
.urlbox .ph{color:var(--accent);background:var(--accent-soft);border-radius:5px;padding:0 5px}
.btn.disabled{opacity:.55;pointer-events:none}
.need-handle{font-size:13.5px;color:var(--warn);margin:8px 0 0}
.tabs{display:inline-flex;gap:4px;padding:4px;border:1px solid var(--line);border-radius:10px;background:var(--surface-2);margin-bottom:12px}
.tabs button{font:500 13.5px var(--sans);padding:7px 12px;border:0;border-radius:7px;background:transparent;color:var(--muted);cursor:pointer}
.tabs button[aria-selected="true"]{background:var(--surface);color:var(--ink);box-shadow:0 1px 2px rgba(0,0,0,.08)}
.keys{font-size:15.5px;line-height:2;margin:2px 0 8px}.keys kbd{margin:0 2px}.keys[hidden]{display:none}
.note{display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border-radius:10px;background:var(--warn-soft);color:var(--ink);font-size:14.5px;max-width:64ch}
.note svg{flex:0 0 auto;color:var(--warn);margin-top:3px}
.note.good{background:var(--good-soft)}.note.good svg{color:var(--good)}
/* mocks */
.mock{margin-top:14px;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:#1e1e1e;color:#d4d4d4;font:13px/1.5 var(--mono);max-width:640px;box-shadow:var(--shadow)}
.mock .bar{display:flex;gap:2px;padding:6px 8px 0;background:#2b2b2b;border-bottom:1px solid #3a3a3a;font:12.5px var(--sans);color:#a9a9a9}
.mock .bar span{padding:6px 10px;border-radius:6px 6px 0 0}
.mock .bar .on{background:#1e1e1e;color:#fff;box-shadow:inset 0 -2px 0 #b3a6ff}
.mock .body{padding:12px 14px;min-height:96px;white-space:pre-wrap;word-break:break-word}
.mock .warn{color:#e9c46a}.mock .prompt{color:#7c7cff}.mock .dim{color:#7a7a7a}.mock .ok{color:#5ee0a8}
.mock .caret{display:inline-block;width:8px;height:15px;background:#d4d4d4;vertical-align:-3px;margin-left:2px}
.panel-mock{margin-top:14px;width:320px;max-width:100%;background:#0d1220;color:#f4f6fb;border:1px solid rgba(255,255,255,.12);border-radius:14px;padding:14px 16px 12px;font:13.5px/1.45 var(--sans);box-shadow:0 20px 50px -20px rgba(0,0,0,.6)}
.panel-mock .h{display:flex;align-items:center;gap:10px;margin-bottom:8px;font:600 11.5px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:#c7cede}
.panel-mock .h i{width:10px;height:10px;border-radius:3px;background:linear-gradient(135deg,#b3a6ff,#5ee0a8)}
.panel-mock .s{color:#5ee0a8}
.panel-mock .p{height:4px;border-radius:2px;background:linear-gradient(90deg,#b3a6ff,#5ee0a8);margin:10px 0 8px}
.panel-mock .f{display:flex;justify-content:space-between;align-items:center;font-size:12px;color:#8f9ab3}
.panel-mock .f{gap:12px}.panel-mock .f b{background:#b3a6ff;color:#0d1220;border-radius:8px;padding:6px 11px;font-size:12.5px;white-space:nowrap;flex:0 0 auto}
/* tools */
.quiet-link{border-color:transparent;color:var(--muted)}.quiet-link:hover{color:var(--accent)}
.tools{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px}
.tool{padding:18px 18px 14px;display:flex;flex-direction:column;gap:8px}
.tool.featured{border-color:color-mix(in srgb,var(--accent) 45%,var(--line))}
.tool h3{margin:0;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.tool .tag{font:500 10.5px var(--mono);padding:2px 7px;border-radius:5px;background:var(--accent-soft);color:var(--accent);text-transform:uppercase;letter-spacing:.06em}
.tool .tag-slow{background:var(--warn-soft);color:var(--warn)}
.tool p{margin:0;color:var(--muted);font-size:14.5px;flex:1}
.tool .page{font:12.5px var(--mono);color:var(--muted);word-break:break-all}
.tool .row{display:flex;gap:8px;margin-top:6px;flex-wrap:wrap}
.group{font:600 12px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:26px 0 12px}
.group:first-of-type{margin-top:0}
/* gallery */
.gallery{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px}
.gallery a{display:block;overflow:hidden;color:inherit;text-decoration:none!important}
.gallery img{display:block;width:100%;height:auto;aspect-ratio:3/2;object-fit:cover;object-position:top}
.gallery b{display:block;padding:12px 14px 4px}.gallery span{display:block;padding:0 14px 12px;color:var(--muted);font-size:13.5px}
/* safety */
.safety{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px}
.safety .card{padding:18px 20px}
.safety .card b{display:flex;align-items:center;gap:8px;margin-bottom:6px}.safety .card b svg{color:var(--good)}
.safety .card p{margin:0;color:var(--muted);font-size:14.5px}
/* troubleshooting + faq */
details{border-top:1px solid var(--line)}
details:last-of-type{border-bottom:1px solid var(--line)}
summary{cursor:pointer;padding:14px 0;font-weight:600;list-style:none;display:flex;justify-content:space-between;gap:12px}
summary::-webkit-details-marker{display:none}
summary::after{content:"+";color:var(--muted);font-weight:400;font-size:20px;line-height:1}
details[open] summary::after{content:"–"}
details p{margin:0 0 14px;color:var(--muted);font-size:15px;max-width:72ch}
.two{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:0 40px}
footer{color:var(--muted);font-size:13px;display:flex;flex-wrap:wrap;gap:8px 20px;justify-content:space-between;padding-top:22px;border-top:1px solid var(--line)}
.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%) translateY(20px);background:var(--ink);color:var(--surface);padding:10px 16px;border-radius:10px;font-size:14px;opacity:0;pointer-events:none;transition:.2s;max-width:calc(100vw - 32px);text-align:center}
.toast.show{opacity:1;transform:translateX(-50%)}
.phone-note{display:none;margin-top:14px}
@media (max-width:860px){.nav .links a[data-nav],.nav .links a[href*="github"]{display:none}.hero{grid-template-columns:1fr;gap:12px;padding-top:36px}.band{padding-bottom:44px}.hero-shot{transform:translateY(64px)}.wrap{padding:0 18px}.content{padding:104px 18px 56px}.nav{flex-wrap:wrap;gap:8px 12px}.nav .brand{white-space:nowrap}.gstep,.gstep.has-aside{grid-template-columns:1fr}.gstep .aside{grid-column:1;margin-top:14px}.gstep::before{margin-bottom:8px}.cta.quiet{margin-left:0;margin-top:8px}}
@media (max-width:640px){.phone-note{display:flex}}
.tool-hero{align-items:start;padding-bottom:64px}
.tool-hero .kicker{display:inline-block;font:600 12px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:#5ee0a8;margin-bottom:14px}
.tool-hero h1{font-size:clamp(32px,4.2vw,50px)}
.tool-hero .hero-shot{transform:none;margin-top:8px}
.facts{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);border-radius:14px;padding:22px 24px;color:var(--band-ink);display:grid;gap:14px;margin-top:8px}
.facts div{display:grid;grid-template-columns:110px minmax(0,1fr);gap:12px;font-size:15px}
.facts b{color:var(--band-muted);font:600 12px var(--mono);letter-spacing:.06em;text-transform:uppercase;padding-top:3px}
.facts .mono{word-break:break-all}
.bullets{margin:0;padding:0;list-style:none;display:grid;gap:12px;max-width:72ch}
.bullets li{display:grid;grid-template-columns:22px minmax(0,1fr);gap:10px;color:var(--ink);font-size:16px}
.bullets li svg{color:var(--good);margin-top:4px}
.section{margin-bottom:64px}
.related{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px}
.related a.card{display:block;padding:18px 20px;color:var(--ink);text-decoration:none}
.related a.card:hover{border-color:var(--accent)}
.related a.card b{display:block;margin-bottom:6px}
.related a.card span{color:var(--muted);font-size:14.5px}
.crumbs{font-size:13.5px;color:var(--band-muted);margin:26px 0 0}.crumbs a{color:var(--band-muted)}.crumbs a:hover{color:var(--band-ink)}
.faq details{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:14px 18px;margin-bottom:10px}
.faq summary{cursor:pointer;font-weight:600}.faq details p{margin:10px 0 0;color:var(--muted);max-width:72ch}
@media (max-width:860px){.tool-hero{grid-template-columns:1fr}.facts div{grid-template-columns:1fr;gap:4px}}
</style>
</head>
<body>
<header class="band">
<div class="wrap">
<nav class="nav" aria-label="Main"><a class="brand" href="/" title="x-utils home"><i></i>x-utils</a><span class="links"><a href="/#how" data-nav="how">How it works</a><a href="/#tools" data-nav="tools">Tools</a><a href="/#examples" data-nav="examples">Examples</a><a href="/#safety" data-nav="safety">Safety</a><a href="/#help" data-nav="help">Help</a><a href="https://github.com/devploit/x-utils" target="_blank" rel="noopener">GitHub</a><a class="go" href="/#start">Start</a></span></nav>
<p class="crumbs"><a href="/">x-utils</a> › <a href="/#tools">Tools</a> › Export your X (Twitter) bookmarks</p>
<div class="hero tool-hero">
<div>
<span class="kicker">Free tool for X (Twitter) · your content</span>
<h1>Export your X (Twitter) bookmarks</h1>
<p>Every bookmark as a readable page with the images, a Markdown file for Notion or Obsidian, and a spreadsheet. Your reading list, finally outside of X.</p>
<div class="pills"><span class="pill"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg>no X API to pay for</span><span class="pill"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg>no install</span><span class="pill"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg>password never asked</span><span class="pill"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg>only reads, changes nothing</span></div>
<button class="cta" type="button" data-copy="bookmarks-export"><svg viewBox="0 0 24 24"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><span>Copy the script</span></button><a class="cta quiet" href="/docs/examples/bookmarks-export.html">See a sample report</a>
</div>
<a class="hero-shot" href="/docs/examples/bookmarks-export.html" aria-label="Open the sample report"><img src="/docs/assets/report-bookmarks.webp" width="2400" height="1520" alt="Sample export your x (twitter) bookmarks report produced by x-utils" fetchpriority="high"></a>
</div>
</div>
</header>
<main class="content wrap">
<section class="section" id="what">
<h2>What you get</h2>
<p class="lead">A self-contained HTML report you can sort, filter and share, plus a CSV for spreadsheets and a JSON file. Everything is built in your browser from what X already shows you when you scroll.</p>
<ul class="bullets">
<li><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg><span>Author, date, text, media and numbers for every bookmark, newest first as X shows them.</span></li>
<li><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg><span>Markdown with one entry per post, ready for a notes app.</span></li>
<li><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg><span>CSV and JSON with links back to the original posts.</span></li>
</ul>
</section>
<section class="section" id="run">
<h2>How to run it</h2>
<p class="lead">Five steps, on a computer. The <a href="/#start">guided setup on the home page</a> adapts them to your system and username.</p>
<div class="card gsteps">
<div class="gstep"><div><h3>Open your bookmarks page on X</h3><p>On a computer, log in to X and open x.com/i/history. If the page was already open, reload it right before pasting: the tool reads the list as X loads it.</p><div class="row"><span class="urlbox">x.com/i/history</span></div></div></div>
<div class="gstep"><div><h3>Open the browser console</h3><p>Press Cmd+Option+I on a Mac or F12 on Windows and Linux, then click the Console tab.</p></div></div>
<div class="gstep"><div><h3>Copy the script</h3><p>Use the copy button on this page. The script is plain text you can read; it lives at x-utils.com/dist/bookmarks-export.js.</p><div class="row"><button class="btn primary" type="button" data-copy="bookmarks-export"><svg viewBox="0 0 24 24"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><span>Copy the script</span></button><a class="btn" href="/dist/bookmarks-export.js" target="_blank" rel="noopener">Open it as a file instead</a></div></div></div>
<div class="gstep"><div><h3>Paste it in the console and press Enter</h3><p>The first time, the browser asks you to type "allow pasting" first. Type it, press Enter, paste again.</p></div></div>
<div class="gstep"><div><h3>Wait, then open your report</h3><p>About a minute per few hundred bookmarks. The report and a CSV land in your Downloads folder.</p></div></div>
</div>
</section>
<section class="section" id="safety">
<h2>Why this is safe</h2>
<div class="safety">
<div class="card"><b><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg>No password, ever</b><p>The script runs inside the X tab where you are already logged in. It never asks for, reads or stores your password, cookies or keys.</p></div>
<div class="card"><b><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg>Nothing is sent anywhere</b><p>There is no server behind this. The report and the spreadsheet are written straight into your Downloads folder.</p></div>
<div class="card"><b><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg>It only reads</b><p>No tool follows, unfollows, blocks, likes, posts or deletes anything. It scrolls and takes notes, like a very fast assistant looking at your screen.</p></div>
<div class="card"><b><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5 9.5 17 19 7"/></svg>Anyone can read it</b><p>The code is open, short, in plain JavaScript and <a href="https://github.com/devploit/x-utils">published on GitHub</a>. If you know a developer, ask them to look.</p></div>
</div>
</section>
<section class="section faq" id="faq">
<h2>Questions</h2>
<details><summary>My bookmarks are at a different address</summary><p>X moved bookmarks to x.com/i/history in 2026. Both that page and the old x.com/i/bookmarks work with the tool.</p></details>
<details><summary>Are images downloaded?</summary><p>The report links to the images on X's servers and shows thumbnails. The files themselves are not copied.</p></details>
<p class="lead" style="margin-top:14px">More answers in the <a href="/#help">help section</a>.</p>
</section>
<section class="section" id="related">
<h2>Related tools</h2>
<div class="related">
<a class="card" href="/likes-export"><b>Export the posts you liked on X (Twitter)</b><span>Everything you liked, as a readable page, a Markdown file and a spreadsheet.</span></a>
<a class="card" href="/thread-unroll"><b>Read a whole X (Twitter) thread as clean text</b><span>Open any post of a thread and get the whole thread as one clean text, a readable page and a Markdown file.</span></a>
<a class="card" href="/search-export"><b>Export X (Twitter) search results</b><span>Any search, including advanced operators such as from:, since: and min_faves:, as a spreadsheet and a readable page.</span></a>
</div>
</section>
<footer><span><a href="/"><b>x-utils</b></a> · made by <a href="https://x.com/devploit" rel="me">@devploit</a> · free and open source (MIT) · not affiliated with X Corp</span><span><a href="https://github.com/devploit/x-utils">Source code</a> · <a href="https://github.com/devploit/x-utils/issues">Report a problem</a></span></footer>
</main>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script>
(function(){
var toast=document.getElementById("toast"),timer;
function say(msg){toast.textContent=msg;toast.classList.add("show");clearTimeout(timer);timer=setTimeout(function(){toast.classList.remove("show")},4200)}
function copyText(text){if(navigator.clipboard&&navigator.clipboard.writeText)return navigator.clipboard.writeText(text);
return new Promise(function(resolve,reject){var ta=document.createElement("textarea");ta.value=text;ta.setAttribute("readonly","");ta.style.position="fixed";ta.style.opacity="0";document.body.appendChild(ta);ta.select();var ok=false;try{ok=document.execCommand("copy")}catch(e){}ta.remove();ok?resolve():reject(new Error("execCommand failed"))})}
document.querySelectorAll("[data-copy]").forEach(function(btn){btn.addEventListener("click",function(){var id=btn.dataset.copy,label=btn.querySelector("span")||btn,orig=label.textContent;
if(location.protocol==="file:"){window.open("dist/"+id+".js","_blank");say("Opened the script in a new tab. Select all, copy, then paste it into the X console.");return}
label.textContent="Copying…";
fetch("/dist/"+id+".js").then(function(r){if(!r.ok)throw new Error(r.status);return r.text()}).then(function(text){if(text.indexOf("x-utils")<0)throw new Error("unexpected content");return copyText(text)}).then(function(){label.textContent="Copied";say("Copied. Now go to the X page, click in the console and paste.");setTimeout(function(){label.textContent=orig},2600)})
.catch(function(){label.textContent=orig;say("Could not copy automatically. Use 'Open it as a file instead', select everything and copy.")})})});
})();
</script>
</body>
</html>