@grove-dev/astro 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
- package/src/components/ActiveFilterChips.astro +20 -0
- package/src/components/CategoryGrid.astro +27 -0
- package/src/components/DirectoryFilters.astro +100 -0
- package/src/components/DirectoryHero.astro +32 -0
- package/src/components/HealthBadge.astro +12 -0
- package/src/components/ItemCard.astro +41 -0
- package/src/components/LensTabs.astro +26 -0
- package/src/components/MethodologyPanel.astro +20 -0
- package/src/components/Pagination.astro +24 -0
- package/src/components/ProjectDetail.astro +166 -0
- package/src/components/ScoreBars.astro +32 -0
- package/src/components/SubmitDraft.astro +137 -0
- package/src/index.ts +17 -0
- package/src/layouts/BaseLayout.astro +32 -0
- package/src/styles.css +675 -0
- package/templates/default/astro.config.mjs +23 -0
- package/templates/default/data/generated/apps.json +1 -0
- package/templates/default/data/generated/repo-stats.json +1 -0
- package/templates/default/package.json +35 -0
- package/templates/default/public/icons/platforms/android.svg +1 -0
- package/templates/default/public/icons/platforms/apple-dark.svg +1 -0
- package/templates/default/public/icons/platforms/apple-light.svg +1 -0
- package/templates/default/public/icons/platforms/chrome.svg +1 -0
- package/templates/default/public/icons/platforms/chromeos.svg +5 -0
- package/templates/default/public/icons/platforms/desktop.svg +4 -0
- package/templates/default/public/icons/platforms/embedded.svg +5 -0
- package/templates/default/public/icons/platforms/ios.svg +1 -0
- package/templates/default/public/icons/platforms/linux.svg +1 -0
- package/templates/default/public/icons/platforms/macos.svg +1 -0
- package/templates/default/public/icons/platforms/ubuntu.svg +1 -0
- package/templates/default/public/icons/platforms/web.svg +5 -0
- package/templates/default/public/icons/platforms/windows.svg +6 -0
- package/templates/default/public/icons/stacks/android.svg +1 -0
- package/templates/default/public/icons/stacks/apple-dark.svg +1 -0
- package/templates/default/public/icons/stacks/apple-light.svg +1 -0
- package/templates/default/public/icons/stacks/capacitor.svg +14 -0
- package/templates/default/public/icons/stacks/dart.svg +1 -0
- package/templates/default/public/icons/stacks/firebase.svg +1 -0
- package/templates/default/public/icons/stacks/flutter.svg +1 -0
- package/templates/default/public/icons/stacks/graphql.svg +1 -0
- package/templates/default/public/icons/stacks/ionic.svg +4 -0
- package/templates/default/public/icons/stacks/java.svg +1 -0
- package/templates/default/public/icons/stacks/javascript.svg +1 -0
- package/templates/default/public/icons/stacks/kotlin.svg +1 -0
- package/templates/default/public/icons/stacks/mongodb.svg +1 -0
- package/templates/default/public/icons/stacks/nodejs.svg +1 -0
- package/templates/default/public/icons/stacks/python.svg +1 -0
- package/templates/default/public/icons/stacks/react-native.svg +1 -0
- package/templates/default/public/icons/stacks/react.svg +1 -0
- package/templates/default/public/icons/stacks/rust.svg +1 -0
- package/templates/default/public/icons/stacks/solidity.svg +1 -0
- package/templates/default/public/icons/stacks/swift.svg +1 -0
- package/templates/default/public/icons/stacks/tensorflow.svg +1 -0
- package/templates/default/public/icons/stacks/typescript.svg +1 -0
- package/templates/default/public/og-image.svg +48 -0
- package/templates/default/public/robots.txt +53 -0
- package/templates/default/src/components/AppCard.astro +248 -0
- package/templates/default/src/components/AppSection.astro +58 -0
- package/templates/default/src/components/AppsIndexRow.astro +230 -0
- package/templates/default/src/components/AppsPagination.astro +147 -0
- package/templates/default/src/components/CategoryGrid.astro +80 -0
- package/templates/default/src/components/ContributorsGrid.astro +105 -0
- package/templates/default/src/components/DecisionRow.astro +219 -0
- package/templates/default/src/components/ExploreByCategory.astro +74 -0
- package/templates/default/src/components/ExploreByStack.astro +102 -0
- package/templates/default/src/components/Hero.astro +176 -0
- package/templates/default/src/components/MinimalAbout.astro +57 -0
- package/templates/default/src/components/OriginalCollection.astro +144 -0
- package/templates/default/src/components/RefinePanel.astro +272 -0
- package/templates/default/src/components/ScoreBars.astro +72 -0
- package/templates/default/src/components/SmartLensTabs.astro +65 -0
- package/templates/default/src/components/StackGrid.astro +95 -0
- package/templates/default/src/components/WhyThisExists.astro +81 -0
- package/templates/default/src/components/icons/Icon.astro +148 -0
- package/templates/default/src/components/layout/BaseLayout.astro +94 -0
- package/templates/default/src/components/layout/Container.astro +18 -0
- package/templates/default/src/components/layout/Footer.astro +145 -0
- package/templates/default/src/components/layout/Header.astro +144 -0
- package/templates/default/src/components/layout/SectionHeader.astro +42 -0
- package/templates/default/src/components/layout/Seo.astro +120 -0
- package/templates/default/src/components/layout/ThemeToggle.astro +97 -0
- package/templates/default/src/data/apps.ts +149 -0
- package/templates/default/src/data/categories.ts +27 -0
- package/templates/default/src/data/config.ts +28 -0
- package/templates/default/src/data/contributors.ts +96 -0
- package/templates/default/src/data/stacks.ts +47 -0
- package/templates/default/src/data/stats.ts +65 -0
- package/templates/default/src/data/types.ts +248 -0
- package/templates/default/src/lib/apps-search.ts +228 -0
- package/templates/default/src/lib/format.ts +36 -0
- package/templates/default/src/lib/lenses.ts +98 -0
- package/templates/default/src/lib/repo.ts +12 -0
- package/templates/default/src/lib/scores.ts +51 -0
- package/templates/default/src/lib/taxonomy-counts.ts +31 -0
- package/templates/default/src/pages/about.astro +433 -0
- package/templates/default/src/pages/apps/[slug].astro +709 -0
- package/templates/default/src/pages/apps/index.astro +669 -0
- package/templates/default/src/pages/contributors.astro +142 -0
- package/templates/default/src/pages/index.astro +66 -0
- package/templates/default/src/pages/sitemap.xml.ts +77 -0
- package/templates/default/src/pages/submit.astro +416 -0
- package/templates/default/src/styles/global.css +84 -0
- package/templates/default/tailwind.config.mjs +130 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Build-time helpers that compute taxonomy counts from generated
|
|
2
|
+
// apps.json. The static taxonomy files hold the canonical list of
|
|
3
|
+
// names + blurbs; counts live here.
|
|
4
|
+
import generatedJson from "../../data/generated/apps.json";
|
|
5
|
+
|
|
6
|
+
type GeneratedApp = { category?: string; stack?: string };
|
|
7
|
+
|
|
8
|
+
function loadApps(): GeneratedApp[] {
|
|
9
|
+
const raw = generatedJson as { apps?: GeneratedApp[] };
|
|
10
|
+
return raw.apps ?? [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const apps = loadApps();
|
|
14
|
+
|
|
15
|
+
export function countByCategory(): Map<string, number> {
|
|
16
|
+
const m = new Map<string, number>();
|
|
17
|
+
for (const a of apps) {
|
|
18
|
+
const k = a.category || "Other";
|
|
19
|
+
m.set(k, (m.get(k) ?? 0) + 1);
|
|
20
|
+
}
|
|
21
|
+
return m;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function countByStack(): Map<string, number> {
|
|
25
|
+
const m = new Map<string, number>();
|
|
26
|
+
for (const a of apps) {
|
|
27
|
+
const k = a.stack || "Other";
|
|
28
|
+
m.set(k, (m.get(k) ?? 0) + 1);
|
|
29
|
+
}
|
|
30
|
+
return m;
|
|
31
|
+
}
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { siteConfig } from "../data/config";
|
|
3
|
+
import BaseLayout from "../components/layout/BaseLayout.astro";
|
|
4
|
+
import Container from "../components/layout/Container.astro";
|
|
5
|
+
|
|
6
|
+
const githubUrl = "https://github.com/tortuvshin/open-apps";
|
|
7
|
+
|
|
8
|
+
// What the directory adds per app — used as chip list in the
|
|
9
|
+
// "What this project provides" card.
|
|
10
|
+
const directoryFields = [
|
|
11
|
+
"App name and repository",
|
|
12
|
+
"Stack and language",
|
|
13
|
+
"Supported platforms",
|
|
14
|
+
"Category and tags",
|
|
15
|
+
"License",
|
|
16
|
+
"GitHub stars and forks",
|
|
17
|
+
"Activity status",
|
|
18
|
+
"Maturity level",
|
|
19
|
+
"Learning value",
|
|
20
|
+
"Contribution readiness",
|
|
21
|
+
"Caveats or missing information",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
// Why real app codebases matter — patterns you can actually study.
|
|
25
|
+
const realAppPatterns = [
|
|
26
|
+
"Project structure",
|
|
27
|
+
"Navigation patterns",
|
|
28
|
+
"State management",
|
|
29
|
+
"API integration",
|
|
30
|
+
"Authentication",
|
|
31
|
+
"Local storage",
|
|
32
|
+
"Platform setup",
|
|
33
|
+
"Build and release configuration",
|
|
34
|
+
"Documentation and contribution practices",
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
// The questions a developer actually has when scanning a list
|
|
38
|
+
// of repos. Drives the curation schema on detail pages.
|
|
39
|
+
const scanQuestions = [
|
|
40
|
+
"Is this a real app or only a demo?",
|
|
41
|
+
"What stack does it use?",
|
|
42
|
+
"Which platforms does it support?",
|
|
43
|
+
"Is it actively maintained?",
|
|
44
|
+
"Is it mature or new?",
|
|
45
|
+
"Is it useful for learning?",
|
|
46
|
+
"Is it beginner-friendly or complex?",
|
|
47
|
+
"Does it have a clear license?",
|
|
48
|
+
"Are there similar apps worth checking?",
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
// Different shapes an app can take. The directory makes those
|
|
52
|
+
// dimensions visible instead of treating every repo as "just
|
|
53
|
+
// another project".
|
|
54
|
+
const appShapes = [
|
|
55
|
+
{ label: "Mature and stable", note: "Long-running, production-ish" },
|
|
56
|
+
{ label: "New and interesting", note: "Recent, worth watching" },
|
|
57
|
+
{ label: "Good for studying architecture", note: "Patterns worth reading" },
|
|
58
|
+
{ label: "Easier for beginners", note: "Smaller, readable" },
|
|
59
|
+
{ label: "Useful but inactive", note: "Stale, still a reference" },
|
|
60
|
+
{ label: "Archived but worth learning from", note: "Patterns outlive the repo" },
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
// Mobile stacks. Flutter is the original; others are being
|
|
64
|
+
// added in order.
|
|
65
|
+
const mobileStacks = [
|
|
66
|
+
{ name: "Flutter", status: "original", note: "Original collection" },
|
|
67
|
+
{ name: "React Native", status: "growing", note: "Second mobile stack" },
|
|
68
|
+
{ name: "Native iOS", status: "growing", note: "Swift / SwiftUI" },
|
|
69
|
+
{ name: "Native Android", status: "growing", note: "Kotlin / Compose" },
|
|
70
|
+
{ name: "Kotlin Multiplatform", status: "growing", note: "Shared mobile + desktop" },
|
|
71
|
+
{ name: "Ionic & Capacitor", status: "planned", note: "Web-tech mobile" },
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
const title = "About — ${siteConfig.name}";
|
|
75
|
+
const description =
|
|
76
|
+
"About ${siteConfig.name} — a static, community-curated directory of real open-source application codebases. Mobile first.";
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
<BaseLayout title={title} description={description}>
|
|
80
|
+
<Container size="narrow">
|
|
81
|
+
<article class="py-12 sm:py-16">
|
|
82
|
+
<nav class="text-2xs text-ink-500 dark:text-ink-400" aria-label="Breadcrumb">
|
|
83
|
+
<a href="/" class="hover:text-ink-900 dark:hover:text-ink-100">Home</a>
|
|
84
|
+
<span class="mx-1.5 text-ink-300 dark:text-ink-700">/</span>
|
|
85
|
+
<span class="text-ink-700 dark:text-ink-300">About</span>
|
|
86
|
+
</nav>
|
|
87
|
+
|
|
88
|
+
{/* ── Hero ─────────────────────────────────────────────────── */}
|
|
89
|
+
<header class="mt-5">
|
|
90
|
+
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
91
|
+
About
|
|
92
|
+
</span>
|
|
93
|
+
<h1 class="mt-1 m-0 text-[1.75rem] sm:text-[2.25rem] font-semibold tracking-[-0.02em] leading-[1.1] text-ink-900 dark:text-ink-100">
|
|
94
|
+
About {siteConfig.name}
|
|
95
|
+
</h1>
|
|
96
|
+
<p class="mt-4 m-0 text-[1rem] sm:text-[1.0625rem] leading-relaxed text-ink-700 dark:text-ink-200 max-w-[62ch]">
|
|
97
|
+
{siteConfig.name} is a static, community-curated directory of real
|
|
98
|
+
open-source application codebases.
|
|
99
|
+
</p>
|
|
100
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-500 dark:text-ink-400 max-w-[62ch]">
|
|
101
|
+
The project started from the Open Source Flutter Apps collection
|
|
102
|
+
and is now being expanded into a broader directory, starting with
|
|
103
|
+
mobile apps.
|
|
104
|
+
</p>
|
|
105
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200 max-w-[62ch]">
|
|
106
|
+
The goal is simple:{" "}
|
|
107
|
+
<em class="not-italic font-medium text-ink-900 dark:text-ink-100">
|
|
108
|
+
make real open-source apps easier to find, understand, compare,
|
|
109
|
+
and learn from.
|
|
110
|
+
</em>
|
|
111
|
+
</p>
|
|
112
|
+
</header>
|
|
113
|
+
|
|
114
|
+
{/* ── Problem ──────────────────────────────────────────────── */}
|
|
115
|
+
<section class="card mt-8 p-5 sm:p-6">
|
|
116
|
+
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
117
|
+
Problem
|
|
118
|
+
</span>
|
|
119
|
+
<h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
120
|
+
Why this exists
|
|
121
|
+
</h2>
|
|
122
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
123
|
+
Open-source app repositories are already available on GitHub.
|
|
124
|
+
</p>
|
|
125
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
126
|
+
But finding useful real app codebases is still not easy.
|
|
127
|
+
</p>
|
|
128
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
129
|
+
A developer often needs to know more than just the repository name
|
|
130
|
+
and description:
|
|
131
|
+
</p>
|
|
132
|
+
|
|
133
|
+
<ul class="m-0 mt-3 grid list-none grid-cols-1 gap-x-5 gap-y-1.5 p-0 sm:grid-cols-2 text-[0.875rem] text-ink-700 dark:text-ink-200">
|
|
134
|
+
{scanQuestions.map((q) => (
|
|
135
|
+
<li class="flex items-baseline gap-2">
|
|
136
|
+
<span aria-hidden="true" class="text-ink-400 dark:text-ink-500">·</span>
|
|
137
|
+
<span>{q}</span>
|
|
138
|
+
</li>
|
|
139
|
+
))}
|
|
140
|
+
</ul>
|
|
141
|
+
|
|
142
|
+
<p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
143
|
+
A plain README list becomes hard to scan as the number of apps
|
|
144
|
+
grows.
|
|
145
|
+
</p>
|
|
146
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
147
|
+
{siteConfig.name} turns that list into a structured directory.
|
|
148
|
+
</p>
|
|
149
|
+
</section>
|
|
150
|
+
|
|
151
|
+
{/* ── What this project provides ───────────────────────────── */}
|
|
152
|
+
<section class="card mt-4 p-5 sm:p-6">
|
|
153
|
+
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
154
|
+
What the directory adds
|
|
155
|
+
</span>
|
|
156
|
+
<h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
157
|
+
What this project provides
|
|
158
|
+
</h2>
|
|
159
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
160
|
+
Each app is organized with useful metadata, not just a link. The
|
|
161
|
+
directory can show information such as:
|
|
162
|
+
</p>
|
|
163
|
+
|
|
164
|
+
<ul class="m-0 mt-4 list-none space-y-1.5 p-0">
|
|
165
|
+
{directoryFields.map((f) => (
|
|
166
|
+
<li class="flex items-baseline gap-2 text-[0.875rem] text-ink-700 dark:text-ink-200">
|
|
167
|
+
<span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
|
|
168
|
+
<span>{f}</span>
|
|
169
|
+
</li>
|
|
170
|
+
))}
|
|
171
|
+
</ul>
|
|
172
|
+
|
|
173
|
+
<p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
174
|
+
This makes it easier to decide whether a repository is worth
|
|
175
|
+
opening.
|
|
176
|
+
</p>
|
|
177
|
+
</section>
|
|
178
|
+
|
|
179
|
+
{/* ── Why real apps matter ─────────────────────────────────── */}
|
|
180
|
+
<section class="card mt-4 p-5 sm:p-6">
|
|
181
|
+
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
182
|
+
Why real apps matter
|
|
183
|
+
</span>
|
|
184
|
+
<h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
185
|
+
Why real app codebases matter
|
|
186
|
+
</h2>
|
|
187
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
188
|
+
Small examples and tutorials are useful, but they do not show how
|
|
189
|
+
real applications grow.
|
|
190
|
+
</p>
|
|
191
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
192
|
+
Real app codebases can show:
|
|
193
|
+
</p>
|
|
194
|
+
|
|
195
|
+
<ul class="m-0 mt-4 flex flex-wrap gap-1.5 p-0">
|
|
196
|
+
{realAppPatterns.map((p) => (
|
|
197
|
+
<li class="inline-flex items-center rounded-md border border-ink-200 bg-ink-50 px-2 py-1 text-2xs font-medium text-ink-700 dark:border-ink-800 dark:bg-ink-900/60 dark:text-ink-300">
|
|
198
|
+
{p}
|
|
199
|
+
</li>
|
|
200
|
+
))}
|
|
201
|
+
</ul>
|
|
202
|
+
|
|
203
|
+
<p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
204
|
+
This project helps developers discover those real examples faster.
|
|
205
|
+
</p>
|
|
206
|
+
</section>
|
|
207
|
+
|
|
208
|
+
{/* ── AI hype ──────────────────────────────────────────────── */}
|
|
209
|
+
<section class="card mt-4 p-5 sm:p-6">
|
|
210
|
+
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
211
|
+
AI hype
|
|
212
|
+
</span>
|
|
213
|
+
<h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
214
|
+
Why this list is still needed
|
|
215
|
+
</h2>
|
|
216
|
+
|
|
217
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
218
|
+
A lot of developer attention right now is on AI coding tools. The
|
|
219
|
+
pitch is familiar: describe the app, the model builds it, ship
|
|
220
|
+
it.
|
|
221
|
+
</p>
|
|
222
|
+
|
|
223
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
224
|
+
This project does not pretend to compete with that. It does
|
|
225
|
+
something different.
|
|
226
|
+
</p>
|
|
227
|
+
|
|
228
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
229
|
+
AI can generate code. It can also generate code that{" "}
|
|
230
|
+
<em class="not-italic font-medium text-ink-900 dark:text-ink-100">looks like an app, runs like an app, and breaks like an app</em>.
|
|
231
|
+
</p>
|
|
232
|
+
|
|
233
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
234
|
+
A generated prototype is not the same as a real application. Real
|
|
235
|
+
apps have structure that survives years of changes, decisions,
|
|
236
|
+
edge cases, and contributors. They handle authentication,
|
|
237
|
+
navigation, storage, releases, deprecation. They have bugs and
|
|
238
|
+
they fix them.
|
|
239
|
+
</p>
|
|
240
|
+
|
|
241
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
242
|
+
That part does not come from prompting a model.
|
|
243
|
+
</p>
|
|
244
|
+
|
|
245
|
+
<p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
246
|
+
{siteConfig.name} is a list of those real applications. Curated by
|
|
247
|
+
humans. Useful as a reference for:
|
|
248
|
+
</p>
|
|
249
|
+
|
|
250
|
+
<ul class="m-0 mt-3 list-none space-y-1.5 p-0 text-[0.875rem] text-ink-700 dark:text-ink-200">
|
|
251
|
+
<li class="flex items-baseline gap-2">
|
|
252
|
+
<span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
|
|
253
|
+
<span>Studying how a real app is structured</span>
|
|
254
|
+
</li>
|
|
255
|
+
<li class="flex items-baseline gap-2">
|
|
256
|
+
<span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
|
|
257
|
+
<span>Comparing two real approaches to the same problem</span>
|
|
258
|
+
</li>
|
|
259
|
+
<li class="flex items-baseline gap-2">
|
|
260
|
+
<span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
|
|
261
|
+
<span>Finding a codebase to learn from</span>
|
|
262
|
+
</li>
|
|
263
|
+
<li class="flex items-baseline gap-2">
|
|
264
|
+
<span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
|
|
265
|
+
<span>Finding a codebase to contribute to</span>
|
|
266
|
+
</li>
|
|
267
|
+
<li class="flex items-baseline gap-2">
|
|
268
|
+
<span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
|
|
269
|
+
<span>Finding a codebase to use as a reference when generating new code</span>
|
|
270
|
+
</li>
|
|
271
|
+
</ul>
|
|
272
|
+
|
|
273
|
+
<p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
274
|
+
AI tools are useful. A curated directory of real codebases is
|
|
275
|
+
also useful. They are not the same thing, and one does not
|
|
276
|
+
replace the other.
|
|
277
|
+
</p>
|
|
278
|
+
|
|
279
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
280
|
+
If you are using an AI tool to build something, you can also use
|
|
281
|
+
this directory to find real apps to point it at.{" "}
|
|
282
|
+
<em class="not-italic font-medium text-ink-900 dark:text-ink-100">
|
|
283
|
+
"Build me an app like this one"
|
|
284
|
+
</em>{" "}
|
|
285
|
+
is a stronger instruction than{" "}
|
|
286
|
+
<em class="not-italic font-medium text-ink-900 dark:text-ink-100">
|
|
287
|
+
"build me an app."
|
|
288
|
+
</em>
|
|
289
|
+
</p>
|
|
290
|
+
|
|
291
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
292
|
+
That is the idea.
|
|
293
|
+
</p>
|
|
294
|
+
</section>
|
|
295
|
+
|
|
296
|
+
{/* ── What makes an app valuable here ──────────────────────── */}
|
|
297
|
+
<section class="card mt-4 p-5 sm:p-6">
|
|
298
|
+
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
299
|
+
Different shapes
|
|
300
|
+
</span>
|
|
301
|
+
<h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
302
|
+
What makes an app valuable here
|
|
303
|
+
</h2>
|
|
304
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
305
|
+
Not every repository is useful in the same way.
|
|
306
|
+
</p>
|
|
307
|
+
|
|
308
|
+
<ul class="m-0 mt-4 list-none space-y-2 p-0">
|
|
309
|
+
{appShapes.map((s) => (
|
|
310
|
+
<li class="flex items-baseline gap-3 text-[0.9375rem]">
|
|
311
|
+
<span aria-hidden="true" class="mt-1.5 inline-block h-1.5 w-1.5 shrink-0 rounded-full bg-ink-400 dark:bg-ink-600"></span>
|
|
312
|
+
<span class="font-medium text-ink-900 dark:text-ink-100">{s.label}</span>
|
|
313
|
+
<span class="text-ink-500 dark:text-ink-400">— {s.note}</span>
|
|
314
|
+
</li>
|
|
315
|
+
))}
|
|
316
|
+
</ul>
|
|
317
|
+
|
|
318
|
+
<p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
319
|
+
The directory should make those differences visible.
|
|
320
|
+
</p>
|
|
321
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
322
|
+
Instead of treating every repository as the same, Open Source
|
|
323
|
+
Apps adds context around each app.
|
|
324
|
+
</p>
|
|
325
|
+
</section>
|
|
326
|
+
|
|
327
|
+
{/* ── Open data ────────────────────────────────────────────── */}
|
|
328
|
+
<section class="card mt-4 p-5 sm:p-6">
|
|
329
|
+
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
330
|
+
How data works
|
|
331
|
+
</span>
|
|
332
|
+
<h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
333
|
+
Open data
|
|
334
|
+
</h2>
|
|
335
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
336
|
+
The project is open-source by design.
|
|
337
|
+
</p>
|
|
338
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
339
|
+
The app data lives in the repository. The website is generated
|
|
340
|
+
from static data. Metadata can be reviewed and improved through
|
|
341
|
+
GitHub issues and pull requests.
|
|
342
|
+
</p>
|
|
343
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
344
|
+
This keeps the project simple, transparent, and
|
|
345
|
+
community-maintainable.
|
|
346
|
+
</p>
|
|
347
|
+
</section>
|
|
348
|
+
|
|
349
|
+
{/* ── Current focus ────────────────────────────────────────── */}
|
|
350
|
+
<section class="card mt-4 p-5 sm:p-6">
|
|
351
|
+
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
352
|
+
Scope right now
|
|
353
|
+
</span>
|
|
354
|
+
<h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
355
|
+
Current focus
|
|
356
|
+
</h2>
|
|
357
|
+
<p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
358
|
+
The first focus is mobile apps.
|
|
359
|
+
</p>
|
|
360
|
+
<p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
361
|
+
The original collection is Flutter-based, so Flutter is the
|
|
362
|
+
strongest starting point. The directory is also designed to
|
|
363
|
+
support other mobile stacks over time:
|
|
364
|
+
</p>
|
|
365
|
+
|
|
366
|
+
<ul class="m-0 mt-4 list-none space-y-1.5 p-0">
|
|
367
|
+
{mobileStacks.map((s) => (
|
|
368
|
+
<li class="flex items-baseline gap-3 text-[0.9375rem]">
|
|
369
|
+
<span
|
|
370
|
+
aria-hidden="true"
|
|
371
|
+
class={`mt-1.5 inline-block h-1.5 w-1.5 shrink-0 rounded-full ${
|
|
372
|
+
s.status === "original"
|
|
373
|
+
? "bg-emerald-500"
|
|
374
|
+
: s.status === "growing"
|
|
375
|
+
? "bg-amber-500"
|
|
376
|
+
: "bg-ink-300 dark:bg-ink-700"
|
|
377
|
+
}`}
|
|
378
|
+
></span>
|
|
379
|
+
<span class="font-medium text-ink-900 dark:text-ink-100">{s.name}</span>
|
|
380
|
+
<span class="text-ink-500 dark:text-ink-400">— {s.note}</span>
|
|
381
|
+
</li>
|
|
382
|
+
))}
|
|
383
|
+
</ul>
|
|
384
|
+
|
|
385
|
+
<p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
386
|
+
Later, the same structure can support other app types such as
|
|
387
|
+
desktop apps.
|
|
388
|
+
</p>
|
|
389
|
+
</section>
|
|
390
|
+
|
|
391
|
+
{/* ── Principle ────────────────────────────────────────────── */}
|
|
392
|
+
<section class="mt-8 rounded-lg border border-ink-200 bg-ink-50/60 p-6 sm:p-7 dark:border-ink-800 dark:bg-ink-900/40">
|
|
393
|
+
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
394
|
+
The principle
|
|
395
|
+
</span>
|
|
396
|
+
<p class="mt-2 m-0 text-[1.125rem] sm:text-[1.375rem] font-semibold leading-[1.25] tracking-tight text-ink-900 dark:text-ink-100">
|
|
397
|
+
Real apps are easier to learn from when they are organized with
|
|
398
|
+
context.
|
|
399
|
+
</p>
|
|
400
|
+
<p class="mt-3 m-0 text-[0.9375rem] sm:text-[1rem] leading-relaxed text-ink-700 dark:text-ink-200">
|
|
401
|
+
{siteConfig.name} exists to make open-source application
|
|
402
|
+
codebases easier to discover, evaluate, and study.
|
|
403
|
+
</p>
|
|
404
|
+
</section>
|
|
405
|
+
|
|
406
|
+
{/* ── CTA ──────────────────────────────────────────────────── */}
|
|
407
|
+
<section class="mt-8 flex flex-wrap items-center gap-3">
|
|
408
|
+
<a
|
|
409
|
+
href="/apps"
|
|
410
|
+
class="btn-primary"
|
|
411
|
+
>
|
|
412
|
+
Browse the directory
|
|
413
|
+
</a>
|
|
414
|
+
<a
|
|
415
|
+
href={githubUrl}
|
|
416
|
+
target="_blank"
|
|
417
|
+
rel="noopener noreferrer"
|
|
418
|
+
class="btn-outline"
|
|
419
|
+
>
|
|
420
|
+
View on GitHub
|
|
421
|
+
</a>
|
|
422
|
+
<a
|
|
423
|
+
href={`${githubUrl}/blob/main/CONTRIBUTING.md`}
|
|
424
|
+
target="_blank"
|
|
425
|
+
rel="noopener noreferrer"
|
|
426
|
+
class="btn-ghost"
|
|
427
|
+
>
|
|
428
|
+
Submit an app →
|
|
429
|
+
</a>
|
|
430
|
+
</section>
|
|
431
|
+
</article>
|
|
432
|
+
</Container>
|
|
433
|
+
</BaseLayout>
|