development
tsx 376 lines 15.3 KB
Raw
1 import type { Metadata } from "next";
2 import Link from "next/link";
3 import { StructuredData } from "@/components/structured-data";
4 import { absoluteUrl, genPageMetadata } from "../seo";
5
6 const comparisonRows = [
7 {
8 label: "Deploy workflow",
9 smbcloud: "Run `smb`, deploy over SSH, and watch the logs.",
10 railway:
11 "Quick platform workflow for apps and services, with more platform around it.",
12 },
13 {
14 label: "Best fit",
15 smbcloud:
16 "Small teams that want a narrower product and a simpler deploy story.",
17 railway: "Teams that like Railway's broader approach and flexibility.",
18 },
19 {
20 label: "Runtime focus",
21 smbcloud: "Node.js, Ruby on Rails, and Swift/Vapor.",
22 railway: "General app platform across more service shapes.",
23 },
24 {
25 label: "Why teams pick it",
26 smbcloud: "Because the smaller surface area feels easier to work with.",
27 railway: "Because they want more flexibility under one roof.",
28 },
29 ];
30
31 const smbcloudFits = [
32 "You want a calmer, more focused deploy flow.",
33 "You are mostly shipping Node.js, Rails, or Vapor.",
34 "You prefer SSH and straightforward app operations.",
35 "You would rather have less platform to think about.",
36 ];
37
38 const railwayStillFits = [
39 "You want one platform for lots of service types.",
40 "Your team already likes how Railway works.",
41 "You need flexibility beyond smbCloud's current focus.",
42 ];
43
44 const bestFor = [
45 "Founders and small product teams",
46 "Agencies that want a repeatable deploy workflow",
47 "Node.js backends and dashboards",
48 "Rails apps",
49 "Vapor apps",
50 ];
51
52 const faqs = [
53 {
54 question: "Is smbCloud better than Railway?",
55 answer:
56 "Depends what you want. If you want a simpler SSH-first deploy flow for Node.js, Rails, or Vapor, maybe yes. If you want a broader platform, probably not.",
57 },
58 {
59 question: "What makes smbCloud different from Railway?",
60 answer: "It is narrower. That is intentional.",
61 },
62 {
63 question: "Who should consider switching from Railway?",
64 answer:
65 "Teams that want less platform in the middle and a deploy flow that feels easier to follow.",
66 },
67 ];
68
69 export const metadata: Metadata = {
70 ...genPageMetadata({
71 title: "Railway alternative for Node.js, Rails, and Vapor",
72 description:
73 "smbCloud is a Railway alternative for small teams that want an SSH-first deploy workflow for Node.js, Ruby on Rails, and Swift/Vapor apps.",
74 path: "/railway-alternative",
75 keywords: [
76 "Railway alternative",
77 "Railway replacement",
78 "SSH-first deploy platform",
79 "deploy Node.js app",
80 "deploy Ruby on Rails app",
81 "deploy Vapor app",
82 "small team hosting platform",
83 ],
84 }),
85 };
86
87 const structuredData = {
88 "@context": "https://schema.org",
89 "@graph": [
90 {
91 "@type": "WebPage",
92 "@id": absoluteUrl("/railway-alternative#webpage"),
93 url: absoluteUrl("/railway-alternative"),
94 name: "Railway alternative for small teams",
95 description:
96 "Compare smbCloud and Railway for small-team app deployment workflows.",
97 isPartOf: {
98 "@id": absoluteUrl("/#website"),
99 },
100 },
101 {
102 "@type": "BreadcrumbList",
103 itemListElement: [
104 {
105 "@type": "ListItem",
106 position: 1,
107 name: "Home",
108 item: absoluteUrl("/"),
109 },
110 {
111 "@type": "ListItem",
112 position: 2,
113 name: "Railway alternative",
114 item: absoluteUrl("/railway-alternative"),
115 },
116 ],
117 },
118 {
119 "@type": "FAQPage",
120 mainEntity: faqs.map((faq) => ({
121 "@type": "Question",
122 name: faq.question,
123 acceptedAnswer: {
124 "@type": "Answer",
125 text: faq.answer,
126 },
127 })),
128 },
129 ],
130 };
131
132 export default function RailwayAlternativePage() {
133 return (
134 <div>
135 <StructuredData data={structuredData} />
136
137 <section className="relative overflow-hidden px-6 pt-24 pb-16 sm:pt-32 sm:pb-20 lg:px-8">
138 <div className="pointer-events-none absolute inset-x-0 top-0 -z-10 h-[520px] bg-[radial-gradient(ellipse_75%_50%_at_50%_0%,rgba(99,102,241,0.18),transparent)] dark:bg-[radial-gradient(ellipse_75%_50%_at_50%_0%,rgba(99,102,241,0.12),transparent)]" />
139
140 <div className="mx-auto max-w-4xl">
141 <div className="mb-6 inline-flex items-center gap-2 rounded-full border border-indigo-200 bg-indigo-50 px-4 py-1.5 dark:border-indigo-500/30 dark:bg-indigo-500/10">
142 <span className="h-1.5 w-1.5 rounded-full bg-indigo-500" />
143 <span className="text-xs font-semibold uppercase tracking-widest text-indigo-700 dark:text-indigo-400">
144 Railway alternative
145 </span>
146 </div>
147
148 <h1 className="max-w-3xl text-4xl font-bold tracking-tight text-slate-900 dark:text-white sm:text-6xl leading-[1.05]">
149 Looking for a Railway alternative?
150 </h1>
151
152 <p className="mt-6 max-w-3xl text-lg leading-8 text-slate-600 dark:text-slate-400">
153 We built smbCloud for teams that like fast deploys but do not want
154 the platform to keep getting bigger around the work. SSH-first, one
155 command, not much ceremony.
156 </p>
157
158 <div className="mt-8 flex flex-col gap-4 sm:flex-row">
159 <Link
160 href="https://console.smbcloud.xyz"
161 target="_blank"
162 rel="noopener noreferrer"
163 className="inline-flex items-center justify-center rounded-lg bg-indigo-600 px-8 py-3.5 text-sm font-semibold text-white shadow-lg shadow-indigo-500/20 transition-all hover:bg-indigo-500 hover:shadow-indigo-500/30 active:scale-[0.98]"
164 >
165 Start deploying
166 </Link>
167 <Link
168 href="/posts/cli"
169 className="inline-flex items-center justify-center rounded-lg border border-slate-300 px-8 py-3.5 text-sm font-semibold text-slate-700 transition-colors hover:bg-slate-50 dark:border-white/[0.12] dark:text-slate-200 dark:hover:bg-white/[0.04]"
170 >
171 Install the CLI
172 </Link>
173 </div>
174 </div>
175 </section>
176
177 <section className="px-6 pb-24 lg:px-8">
178 <div className="mx-auto max-w-5xl grid gap-8 lg:grid-cols-[0.95fr_1.05fr]">
179 <div>
180 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
181 Why people leave Railway
182 </p>
183 <h2 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white">
184 Usually they are not asking for more features. They want less to
185 think about.
186 </h2>
187 <p className="mt-5 text-base leading-8 text-slate-600 dark:text-slate-400">
188 Railway is fast to get started with. I get the appeal. But some
189 teams eventually decide the broader platform is not actually the
190 part they wanted.
191 </p>
192 </div>
193
194 <div className="rounded-2xl border border-slate-200 bg-slate-50 p-8 dark:border-white/[0.06] dark:bg-white/[0.02]">
195 <p className="text-sm font-semibold text-slate-900 dark:text-white">
196 What smbCloud does well
197 </p>
198 <ul className="mt-5 space-y-4 text-sm leading-7 text-slate-600 dark:text-slate-400">
199 <li className="flex gap-3">
200 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
201 <span>Deploy over SSH with one command.</span>
202 </li>
203 <li className="flex gap-3">
204 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
205 <span>Support for Node.js, Rails, and Swift/Vapor.</span>
206 </li>
207 <li className="flex gap-3">
208 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
209 <span>A smaller surface area, which is kind of the point.</span>
210 </li>
211 </ul>
212 </div>
213 </div>
214 </section>
215
216 <section className="border-t border-slate-200 px-6 py-24 dark:border-white/[0.06] lg:px-8">
217 <div className="mx-auto max-w-5xl">
218 <div className="mb-12 max-w-3xl">
219 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
220 smbCloud vs Railway
221 </p>
222 <h2 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white">
223 If you want a focused platform, this is the trade.
224 </h2>
225 </div>
226
227 <div className="overflow-hidden rounded-2xl border border-slate-200 dark:border-white/[0.06]">
228 <div className="grid grid-cols-[0.8fr_1fr_1fr] bg-slate-50 text-sm font-semibold text-slate-900 dark:bg-white/[0.03] dark:text-white">
229 <div className="border-b border-slate-200 px-5 py-4 dark:border-white/[0.06]">
230 Area
231 </div>
232 <div className="border-b border-l border-slate-200 px-5 py-4 dark:border-white/[0.06]">
233 smbCloud
234 </div>
235 <div className="border-b border-l border-slate-200 px-5 py-4 dark:border-white/[0.06]">
236 Railway
237 </div>
238 </div>
239 {comparisonRows.map((row) => (
240 <div
241 key={row.label}
242 className="grid grid-cols-[0.8fr_1fr_1fr] text-sm leading-7 text-slate-600 dark:text-slate-400"
243 >
244 <div className="border-b border-slate-200 bg-white px-5 py-5 font-semibold text-slate-900 dark:border-white/[0.06] dark:bg-white/[0.02] dark:text-white">
245 {row.label}
246 </div>
247 <div className="border-b border-l border-slate-200 bg-white px-5 py-5 dark:border-white/[0.06] dark:bg-white/[0.02]">
248 {row.smbcloud}
249 </div>
250 <div className="border-b border-l border-slate-200 bg-white px-5 py-5 dark:border-white/[0.06] dark:bg-white/[0.02]">
251 {row.railway}
252 </div>
253 </div>
254 ))}
255 </div>
256 </div>
257 </section>
258
259 <section className="px-6 py-24 lg:px-8">
260 <div className="mx-auto grid max-w-5xl gap-6 lg:grid-cols-2">
261 <div className="rounded-2xl border border-slate-200 bg-white p-8 dark:border-white/[0.06] dark:bg-white/[0.02]">
262 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
263 Pick smbCloud if
264 </p>
265 <ul className="mt-6 space-y-4 text-sm leading-7 text-slate-600 dark:text-slate-400">
266 {smbcloudFits.map((item) => (
267 <li key={item} className="flex gap-3">
268 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
269 <span>{item}</span>
270 </li>
271 ))}
272 </ul>
273 </div>
274
275 <div className="rounded-2xl border border-slate-200 bg-slate-50 p-8 dark:border-white/[0.06] dark:bg-white/[0.02]">
276 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
277 Stay on Railway if
278 </p>
279 <ul className="mt-6 space-y-4 text-sm leading-7 text-slate-600 dark:text-slate-400">
280 {railwayStillFits.map((item) => (
281 <li key={item} className="flex gap-3">
282 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-slate-400" />
283 <span>{item}</span>
284 </li>
285 ))}
286 </ul>
287 </div>
288 </div>
289 </section>
290
291 <section className="border-t border-slate-200 px-6 py-24 dark:border-white/[0.06] lg:px-8">
292 <div className="mx-auto max-w-5xl grid gap-8 lg:grid-cols-[0.95fr_1.05fr]">
293 <div>
294 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
295 Best fit
296 </p>
297 <h2 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white">
298 I would look at smbCloud if you keep thinking, "I just want to
299 deploy the app."
300 </h2>
301 </div>
302 <ul className="rounded-2xl border border-slate-200 bg-white p-8 text-sm leading-7 text-slate-600 dark:border-white/[0.06] dark:bg-white/[0.02] dark:text-slate-400">
303 {bestFor.map((item) => (
304 <li
305 key={item}
306 className="flex gap-3 border-b border-slate-200 py-3 last:border-0 last:pb-0 first:pt-0 dark:border-white/[0.06]"
307 >
308 <span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-indigo-500" />
309 <span>{item}</span>
310 </li>
311 ))}
312 </ul>
313 </div>
314 </section>
315
316 <section className="px-6 pb-24 lg:px-8">
317 <div className="mx-auto max-w-3xl">
318 <div className="mb-10">
319 <p className="text-xs font-bold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-600">
320 FAQ
321 </p>
322 <h2 className="mt-4 text-3xl font-bold tracking-tight text-slate-900 dark:text-white">
323 Common questions
324 </h2>
325 </div>
326 <div className="space-y-4">
327 {faqs.map((faq) => (
328 <div
329 key={faq.question}
330 className="rounded-2xl border border-slate-200 bg-white p-6 dark:border-white/[0.06] dark:bg-white/[0.02]"
331 >
332 <h3 className="text-lg font-semibold text-slate-900 dark:text-white">
333 {faq.question}
334 </h3>
335 <p className="mt-3 text-sm leading-7 text-slate-600 dark:text-slate-400">
336 {faq.answer}
337 </p>
338 </div>
339 ))}
340 </div>
341 </div>
342 </section>
343
344 <section className="px-6 pb-20 lg:px-8">
345 <div className="mx-auto max-w-3xl">
346 <div className="relative overflow-hidden rounded-2xl bg-indigo-600 px-8 py-14 text-center shadow-2xl shadow-indigo-500/20">
347 <div className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_at_top,rgba(255,255,255,0.1),transparent)]" />
348 <h2 className="relative text-3xl font-bold tracking-tight text-white">
349 If Railway feels a bit too broad, try smbCloud.
350 </h2>
351 <p className="relative mt-4 text-indigo-200">
352 Try it on one app. You will know pretty quickly if the smaller
353 workflow is what you wanted.
354 </p>
355 <div className="relative mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
356 <Link
357 href="https://console.smbcloud.xyz"
358 target="_blank"
359 rel="noopener noreferrer"
360 className="inline-flex rounded-lg bg-white px-8 py-3.5 text-sm font-semibold text-indigo-700 shadow-sm transition-colors hover:bg-indigo-50"
361 >
362 Try smbCloud
363 </Link>
364 <Link
365 href="/heroku-alternative"
366 className="inline-flex rounded-lg border border-white/20 px-8 py-3.5 text-sm font-semibold text-white transition-colors hover:bg-white/10"
367 >
368 Compare Heroku alternative
369 </Link>
370 </div>
371 </div>
372 </div>
373 </section>
374 </div>
375 );
376 }