Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mastodon
GitHub Repository: mastodon/joinmastodon
Path: blob/main/pages/about/index.tsx
1006 views
1
// About
2
import Head from "next/head"
3
import Hero from "../../components/Hero"
4
import { withDefaultStaticProps } from "../../utils/defaultStaticProps"
5
import Layout from "../../components/Layout"
6
import heroImage from "../../public/illustrations/apps_hero_desktop.png"
7
import Image from "next/legacy/image"
8
import { FormattedDate, FormattedMessage } from "react-intl"
9
import Link from "next/link"
10
import { useQuery } from "@tanstack/react-query"
11
import Statistic from "../../components/Statistic"
12
import team from "../../data/team"
13
import board from "../../data/board"
14
import interviews from "../../data/interviews"
15
import press from "../../data/press"
16
import LinkWithArrow from "../../components/LinkWithArrow"
17
import PressArticle from "../../components/PressArticle"
18
import { mapBoardPositionToLabel } from "../../utils/map"
19
20
import PersonIcon from "../../public/ui/person.svg?inline"
21
import FiltersIcon from "../../public/ui/filters.svg?inline"
22
import LogoWhite from "../../public/logos/logo-white.svg?inline"
23
24
const About = () => (
25
<Layout>
26
<div dir="ltr" className="[unicode-bidi:plaintext]">
27
<Hero desktopImage={heroImage} mobileImage={heroImage}>
28
<h1 className="h1 mb-8 pt-16">We develop Mastodon</h1>
29
<p className="sh1">Free, open-source decentralized social media</p>
30
</Hero>
31
32
<div className="full-width-bg">
33
<div className="full-width-bg__inner">
34
<div className="grid grid-cols-12 gap-y-24 py-20 md:gap-x-12">
35
<div className="col-span-12 md:col-span-6">
36
<h2 className="h3 mb-6">Our story</h2>
37
38
<p className="b1 mb-4">
39
<strong>
40
Mastodon is a non-profit that develops the
41
Mastodon software.
42
</strong>{" "}
43
Mastodon started in 2016 as an open-source project by Eugen
44
Rochko, who, as an avid user since 2008, was dissatisfied with
45
the state and direction of Twitter.
46
</p>
47
<p className="b1 mb-4">
48
Believing that instant global communications were too crucial
49
for modern society to belong to a single commercial company, he
50
sought to build a user-friendly microblogging product that would
51
not belong to any central authority, but remain practical for
52
everyday use.
53
</p>
54
<p className="b1 mb-4">
55
The first public launch occurred in October 2016. The initial
56
support the project received through Patreon ensured that Eugen
57
could begin working on the project full-time post-graduation. In
58
April 2017 it received its first big break and garnered
59
world-wide attention and press coverage.
60
</p>
61
<p className="b1 mb-6">
62
The project was officially incorporated as a gGmbH (a German
63
form of non-profit LLC) in 2021 but lost its non-profit status
64
when Germany removed software projects from eligibility. In
65
2025, the team began the process of moving the project to a new
66
foundation, and began implementing community governance.
67
</p>
68
69
<ul className="b1 space-y-4">
70
<li>
71
<LinkWithArrow href="/branding">Branding</LinkWithArrow>
72
</li>
73
<li>
74
<LinkWithArrow href="/trademark">
75
Trademark Policy
76
</LinkWithArrow>
77
</li>
78
</ul>
79
</div>
80
81
<div className="col-span-12 md:col-span-6">
82
<h2 className="h3 mb-6" id="team">
83
Meet the team
84
</h2>
85
86
<p className="b1 mb-6">
87
<LinkWithArrow href="/careers">Join the team</LinkWithArrow>
88
</p>
89
90
<div className="grid grid-cols-12 gap-gutter">
91
{team.map((member) => (
92
<div
93
key={member.name}
94
className="col-span-6 lg:col-span-4 mb-6"
95
>
96
{/* <div className="relative mb-4 aspect-video w-full overflow-hidden rounded-lg bg-blurple-gradient shadow">
97
{member.image && (
98
<Image
99
src={member.image}
100
layout="fill"
101
objectFit="cover"
102
objectPosition="50% 50%"
103
alt=""
104
className="grayscale"
105
/>
106
)}
107
</div> */}
108
109
<div className="flex items-center">
110
<span className="b2 block flex-grow !font-bold">
111
{member.name}
112
</span>
113
114
{member.socials && (
115
<a
116
href={member.socials.mastodon}
117
rel="me"
118
className="b2 ml-2 block flex-shrink-0 text-blurple-600 hover:text-blurple-500"
119
>
120
<LogoWhite
121
className="h-[1em] w-[1em]"
122
fill="currentColor"
123
/>
124
</a>
125
)}
126
</div>
127
128
<div className="flex items-center">
129
<span className="b2 block flex-grow !font-semibold text-gray-1">
130
{member.position}
131
</span>
132
</div>
133
</div>
134
))}
135
</div>
136
</div>
137
138
<div className="col-span-12 md:col-span-6">
139
<h2 className="h3 mb-6">Mastodon, Inc.</h2>
140
141
<p className="b1 mb-4">
142
Mastodon, Inc. (EIN 92-3333630) is a 501(c)(3) non-profit entity
143
in the United States that supports the growth and operational
144
capabilities of Mastodon, including being able to receive
145
tax-deductible U.S. donations and in-kind support.
146
</p>
147
<dl className="b1">
148
<dt className="font-bold">Address:</dt>
149
<dd>
150
<address className="not-italic">
151
Mastodon Inc,
152
<br />
153
228 East 45th Street Suite 9E
154
<br />
155
New York, New York 10017
156
</address>
157
</dd>
158
</dl>
159
</div>
160
161
<div className="col-span-12 md:col-span-6">
162
<a id="us-board" className="invisible block relative -top-32" />
163
<h2 className="h3 mb-6" id="board_of_directors">
164
Meet the Board
165
</h2>
166
<div className="grid grid-cols-12 gap-gutter">
167
{board.map((member) => (
168
<div
169
key={member.name}
170
className="col-span-6 lg:col-span-4 mb-6"
171
>
172
<div className="flex items-center">
173
<span className="b2 block flex-grow !font-bold">
174
{member.slug ? (
175
<Link
176
key={`about/${member.slug}`}
177
href={`/about/${member.slug}`}
178
locale={false}
179
className="text-blurple-600 hocus:underline"
180
>
181
{member.name}
182
</Link>
183
) : (
184
member.name
185
)}
186
</span>
187
188
{member.socials && (
189
<a
190
href={member.socials.mastodon}
191
rel="me"
192
className="b2 ml-2 block flex-shrink-0 text-blurple-600 hover:text-blurple-500"
193
>
194
<LogoWhite
195
className="h-[1em] w-[1em]"
196
fill="currentColor"
197
/>
198
</a>
199
)}
200
</div>
201
202
<div className="flex items-center">
203
<span className="b2 block flex-grow !font-semibold text-gray-1">
204
{mapBoardPositionToLabel(member.position)}
205
</span>
206
</div>
207
{member.title && (
208
<div className="flex items-center">
209
<span className="b2 block flex-grow !font-bold">
210
{member.title}
211
</span>
212
</div>
213
)}
214
</div>
215
))}
216
</div>
217
</div>
218
219
<div className="col-span-12 md:col-span-3">
220
<h2 className="h3 mb-4">Our metrics</h2>
221
222
<Metrics />
223
</div>
224
225
<div className="col-span-12 md:col-span-3">
226
<a id="reports" className="invisible relative -top-32" />
227
<h2 className="h3 mb-4">Reports</h2>
228
229
<ul className="list-disc pl-3">
230
<li>
231
<a
232
href="/reports/Mastodon Annual Report 2024.pdf"
233
className="b2 block hover:text-blurple-500"
234
>
235
<span className="h5 block">2024</span>
236
<span className="text-gray-2">PDF, 4.2 MB</span>
237
</a>
238
</li>
239
<li>
240
<a
241
href="/reports/Mastodon Annual Report 2023.pdf"
242
className="b2 block hover:text-blurple-500"
243
>
244
<span className="h5 block">2023</span>
245
<span className="text-gray-2">PDF, 4 MB</span>
246
</a>
247
</li>
248
249
<li>
250
<a
251
href="/reports/Mastodon Annual Report 2022.pdf"
252
className="b2 block hover:text-blurple-500"
253
>
254
<span className="h5 block">2022</span>
255
<span className="text-gray-2">PDF, 6 MB</span>
256
</a>
257
</li>
258
259
<li>
260
<a
261
href="/reports/Mastodon Annual Report 2021.pdf"
262
className="b2 block hover:text-blurple-500"
263
>
264
<span className="h5 block">2021</span>
265
<span className="text-gray-2">PDF, 316 KB</span>
266
</a>
267
</li>
268
</ul>
269
</div>
270
271
<div className="col-span-12 md:col-span-6">
272
<h2 className="h3 mb-4">Podcast interviews</h2>
273
274
<div className="space-y-4">
275
{interviews
276
.sort((a, b) => a.date.localeCompare(b.date) * -1)
277
.map((interview) => (
278
<a
279
key={interview.url}
280
href={interview.url}
281
rel="nofollow noopener"
282
className="group flex max-w-full items-center hover:text-blurple-500"
283
>
284
<div className="relative h-20 w-20 shrink-0 overflow-hidden rounded-md ring-blurple-500 group-hover:ring-2">
285
<Image
286
src={interview.icon}
287
alt=""
288
layout="fill"
289
objectFit="contain"
290
/>
291
</div>
292
293
<div className="truncate px-4">
294
<span className="b1 block truncate !font-bold">
295
{interview.title}
296
</span>
297
<span className="b2 text-gray-1">
298
<FormattedDate
299
value={interview.date}
300
year="numeric"
301
month="short"
302
day="2-digit"
303
/>{" "}
304
<strong>{interview.show}</strong>
305
</span>
306
</div>
307
</a>
308
))}
309
</div>
310
</div>
311
312
<div className="col-span-12">
313
<h2 className="h3 mb-4">In the press</h2>
314
<p className="sh1 mb-8 text-gray-2">
315
What others write about us.
316
</p>
317
318
<div className="grid grid-cols-12 gap-gutter">
319
{press
320
.sort((a, b) => a.date.localeCompare(b.date) * -1)
321
.map((story) => (
322
<PressArticle key={story.url} story={story} />
323
))}
324
</div>
325
</div>
326
327
<div className="col-span-12 md:col-span-6">
328
<a id="contact" className="invisible block relative -top-32" />
329
<h2 className="h3 mb-4">Contact us</h2>
330
331
<div className="b1 mb-4">
332
<dt className="font-bold">Press and media:</dt>
333
<dd className="b3">
334
Media requests, interviews, and press-related questions
335
</dd>
336
<dd>
337
<a
338
href="mailto:[email protected]"
339
className="text-blurple-500 hover:underline"
340
>
341
[email protected]
342
</a>
343
</dd>
344
</div>
345
346
<div className="b1 mb-4">
347
<dt className="font-bold">Business hosting:</dt>
348
<dd className="b3">
349
Supporting organisations joining Mastodon
350
</dd>
351
<dd>
352
<a
353
href="mailto:[email protected]"
354
className="text-blurple-500 hover:underline"
355
>
356
[email protected]
357
</a>
358
</dd>
359
</div>
360
361
<div className="b1 mb-4">
362
<dt className="font-bold">Sponsor assistance:</dt>
363
<dd className="b3">
364
Support for sponsor listings, donations (
365
<Link
366
key="sponsorship"
367
href="/sponsors"
368
className="text-blurple-500 hocus:underline"
369
>
370
sponsorship info
371
</Link>
372
)
373
</dd>
374
<dd>
375
<a
376
href="mailto:[email protected]"
377
className="text-blurple-500 hover:underline"
378
>
379
[email protected]
380
</a>
381
</dd>
382
</div>
383
384
<div className="b1 mb-4">
385
<dt className="font-bold">Legal and trademarks:</dt>
386
<dd className="b3">
387
Legal and compliance, trademarks (
388
<Link
389
key="trademark"
390
href="/trademark"
391
className="text-blurple-500 hocus:underline"
392
>
393
policy
394
</Link>
395
)
396
</dd>{" "}
397
<dd>
398
<a
399
href="mailto:[email protected]"
400
className="text-blurple-500 hover:underline"
401
>
402
[email protected]
403
</a>
404
</dd>
405
</div>
406
407
<div className="b1 mb-4">
408
<dt className="font-bold">Server instance list:</dt>
409
<dd className="b3">
410
Submissions to the server directory (
411
<Link
412
key="servers"
413
href="/covenant"
414
className="text-blurple-500 hocus:underline"
415
>
416
policy
417
</Link>
418
)
419
</dd>
420
<dd>
421
<a
422
href="mailto:[email protected]"
423
className="text-blurple-500 hover:underline"
424
>
425
[email protected]
426
</a>
427
</dd>
428
</div>
429
430
<div className="b1 mb-4">
431
<dt className="font-bold">Security issue reporting:</dt>
432
<dd className="b3">
433
For reporting security vulnerabilities or concerns
434
</dd>
435
<dd>
436
<a
437
href="mailto:[email protected]"
438
className="text-blurple-500 hover:underline"
439
>
440
[email protected]
441
</a>
442
</dd>
443
</div>
444
445
<div className="b1 mb-4">
446
<dt className="font-bold">Any other inquiries:</dt>
447
<dd className="b3">
448
For general questions and all other matters
449
</dd>
450
<dd>
451
<a
452
href="mailto:[email protected]"
453
className="text-blurple-500 hover:underline"
454
>
455
[email protected]
456
</a>
457
</dd>
458
</div>
459
</div>
460
461
<div className="col-span-12 md:col-span-6" id="impressum">
462
<h2 className="h3 mb-4">Impressum</h2>
463
464
<dl className="b1 grid grid-cols-12 gap-gutter">
465
<div className="col-span-6">
466
<div className="mb-4">
467
<dt className="font-bold">Firmenname:</dt>
468
<dd>Mastodon GmbH</dd>
469
</div>
470
471
<div className="mb-4">
472
<dt className="font-bold">Anschrift:</dt>
473
<dd>
474
<address className="not-italic">
475
Mühlenstraße 8a
476
<br />
477
14167 Berlin
478
<br />
479
Germany
480
</address>
481
</dd>
482
</div>
483
484
<div className="mb-4">
485
<dt className="font-bold">Kontakt:</dt>
486
<dd>
487
<a
488
href="mailto:[email protected]"
489
className="text-blurple-500 hover:underline"
490
>
491
[email protected]
492
</a>
493
</dd>
494
</div>
495
</div>
496
497
<div className="col-span-6">
498
<div className="mb-4">
499
<dt className="font-bold">Handelsregister:</dt>
500
<dd>HRB 230086 B (Amtsgericht Charlottenburg)</dd>
501
</div>
502
503
<div className="mb-4">
504
<dt className="font-bold">USt-ID:</dt>
505
<dd>DE344258260</dd>
506
</div>
507
</div>
508
509
<div className="col-span-12 mb-4">
510
<dt className="font-bold">Vertretungsberechtigt:</dt>
511
<dd>Felix Hlatky (Geschäftsführer)</dd>
512
<dd>Dr. Marius Rothermund (Geschäftsführer)</dd>
513
</div>
514
</dl>
515
</div>
516
</div>
517
</div>
518
</div>
519
520
<Head>
521
<title>About - Mastodon</title>
522
<meta property="og:title" content="The company behind Mastodon" />
523
<meta
524
property="og:description"
525
content="Our story, mission, annual reports, interviews, press releases and more."
526
/>
527
<meta
528
property="description"
529
content="Our story, mission, annual reports, interviews, press releases and more."
530
/>
531
</Head>
532
</div>
533
</Layout>
534
)
535
536
const Metrics = () => {
537
const days = useQuery({
538
queryKey: ["statistics"],
539
540
queryFn: () =>
541
fetch("https://api.joinmastodon.org/statistics").then((res) =>
542
res.json()
543
),
544
545
gcTime: 30 * 60 * 1000,
546
})
547
548
if (days.isError || days.isLoading) {
549
return null
550
}
551
552
const currentDay = days.data[days.data.length - 2]
553
const compareDay = days.data[0]
554
555
return (
556
<>
557
<div className="space-y-4">
558
<Statistic
559
key="mau"
560
Icon={PersonIcon}
561
label={
562
<FormattedMessage
563
id="stats.monthly_active_users"
564
defaultMessage="Monthly Active Users"
565
/>
566
}
567
currentValue={parseInt(currentDay.active_user_count)}
568
prevValue={parseInt(compareDay.active_user_count)}
569
/>
570
571
<Statistic
572
key="servers"
573
Icon={FiltersIcon}
574
label={
575
<FormattedMessage id="stats.servers" defaultMessage="Servers Up" />
576
}
577
currentValue={parseInt(currentDay.server_count)}
578
prevValue={parseInt(compareDay.server_count)}
579
/>
580
</div>
581
582
<p className="b3 mt-4 text-gray-2">
583
<FormattedMessage
584
id="stats.disclaimer"
585
defaultMessage="Data collected by crawling all accessible Mastodon servers on {date}."
586
values={{
587
date: (
588
<FormattedDate
589
value={currentDay.period}
590
year="numeric"
591
month="short"
592
day="2-digit"
593
/>
594
),
595
}}
596
/>
597
</p>
598
</>
599
)
600
}
601
602
export const getStaticProps = withDefaultStaticProps()
603
604
export default About
605
606