{authorImageUrl && (
diff --git a/apps/www/components/OpenSourceSection.tsx b/apps/www/components/OpenSourceSection.tsx
new file mode 100644
index 0000000000000..781a0169c7b86
--- /dev/null
+++ b/apps/www/components/OpenSourceSection.tsx
@@ -0,0 +1,57 @@
+import Link from 'next/link'
+import { Button } from 'ui'
+import SectionContainer from './Layouts/SectionContainer'
+import { useSendTelemetryEvent } from '~/lib/telemetry'
+import { kFormatter } from '~/lib/helpers'
+import staticContent from '.generated/staticContent/_index.json'
+
+const OpenSourceSection = () => {
+ const sendTelemetryEvent = useSendTelemetryEvent()
+
+ return (
+
+ Open source from day one
+
+ Supabase is built in the open because we believe great developer tools should be
+ transparent, inspectable, and owned by the community. Read, contribute, self-host. You're
+ never locked in, and always in control.
+
+
+
+
+
+ }
+ asChild
+ size="small"
+ type="default"
+ className="!pl-2.5"
+ >
+ sendTelemetryEvent({ action: 'homepage_github_button_clicked' })}
+ >
+ @supabase
+ {staticContent.githubStars != null && (
+ <>
+
+ {kFormatter(staticContent.githubStars)}
+ >
+ )}
+
+
+
Top 100 GitHub repos
+
+
+ )
+}
+
+export default OpenSourceSection
diff --git a/apps/www/data/solutions/developers.tsx b/apps/www/data/solutions/developers.tsx
index 31a440f5da5f3..7749403a4dbb1 100644
--- a/apps/www/data/solutions/developers.tsx
+++ b/apps/www/data/solutions/developers.tsx
@@ -823,83 +823,22 @@ The output should use the following instructions:
apiExamples: [
{
lang: 'json',
- title: 'macOS',
+ title: 'Hosted',
code: `{
-"mcpServers": {
- "supabase": {
- "command": "npx",
- "args": [
- "-y",
- "@supabase/mcp-server-supabase@latest",
- "--read-only",
- "--project-ref=
"
- ],
- "env": {
- "SUPABASE_ACCESS_TOKEN": ""
- }
- }
-}
-}`,
- },
- {
- lang: 'json',
- title: 'Windows',
- code: `{
-"mcpServers": {
- "supabase": {
- "command": "cmd",
- "args": [
- "/c",
- "npx",
- "-y",
- "@supabase/mcp-server-supabase@latest",
- "--read-only",
- "--project-ref="
- ],
- "env": {
- "SUPABASE_ACCESS_TOKEN": ""
- }
- }
-}
-}`,
- },
- {
- lang: 'json',
- title: 'Windows (WSL)',
- code: `{
-"mcpServers": {
- "supabase": {
- "command": "wsl",
- "args": [
- "npx",
- "-y",
- "@supabase/mcp-server-supabase@latest",
- "--read-only",
- "--project-ref="
- ],
- "env": {
- "SUPABASE_ACCESS_TOKEN": ""
+ "mcpServers": {
+ "supabase": {
+ "url": "https://mcp.supabase.com/mcp"
}
}
-}
}`,
},
{
lang: 'json',
- title: 'Linux',
+ title: 'CLI',
code: `{
"mcpServers": {
"supabase": {
- "command": "npx",
- "args": [
- "-y",
- "@supabase/mcp-server-supabase@latest",
- "--read-only",
- "--project-ref="
- ],
- "env": {
- "SUPABASE_ACCESS_TOKEN": ""
- }
+ "url": "http://localhost:54321/mcp"
}
}
}`,
diff --git a/apps/www/lib/helpers.tsx b/apps/www/lib/helpers.tsx
index fb70995ed9c05..804a065a6f7b0 100644
--- a/apps/www/lib/helpers.tsx
+++ b/apps/www/lib/helpers.tsx
@@ -89,6 +89,38 @@ export const startCase = (string: string): string => {
* @param options The options object
* @returns Returns the new debounced function
*/
+/**
+ * Formats numbers into thousands (K) notation with intelligent decimal handling.
+ * Returns raw number string for values < 1000 to avoid "0K"/"0.xK" outputs.
+ * @param value The value to format (number, string, null, or undefined)
+ * @returns Formatted string (e.g., "999", "1K", "12.5K")
+ */
+export const kFormatter = (value: number | string | null | undefined): string => {
+ // Coerce to safe number, guarding against NaN
+ const num = Number(value ?? 0)
+ const safeNum = isNaN(num) ? 0 : num
+
+ // Early return for values less than 1000
+ if (safeNum < 1000) {
+ return String(Math.floor(safeNum))
+ }
+
+ const kFormat = Math.floor(safeNum / 1000)
+ const lastTwoDigits = safeNum % 1000
+
+ const decimalPart = Math.floor((lastTwoDigits % 100) / 10)
+ const hundreds = Math.floor(lastTwoDigits / 100)
+
+ const isAlmostNextThousand = decimalPart >= 8 && hundreds >= 9
+
+ const showDecimals =
+ (!isAlmostNextThousand && hundreds >= 1) || (hundreds === 0 && decimalPart >= 8)
+
+ return showDecimals
+ ? `${kFormat}.${decimalPart >= 8 ? hundreds + 1 : hundreds}K`
+ : `${isAlmostNextThousand ? kFormat + 1 : kFormat}K`
+}
+
export const debounce = any>(
func: T,
wait: number,
diff --git a/apps/www/pages/index.tsx b/apps/www/pages/index.tsx
index a51d8e6a6a5fa..e466d15868f0b 100644
--- a/apps/www/pages/index.tsx
+++ b/apps/www/pages/index.tsx
@@ -10,6 +10,7 @@ const CustomerStories = dynamic(() => import('components/CustomerStories'))
const BuiltWithSupabase = dynamic(() => import('components/BuiltWithSupabase'))
const DashboardFeatures = dynamic(() => import('~/components/DashboardFeatures'))
const TwitterSocialSection = dynamic(() => import('~/components/TwitterSocialSection'))
+const OpenSourceSection = dynamic(() => import('~/components/OpenSourceSection'))
const CTABanner = dynamic(() => import('components/CTABanner/index'))
const Index = () => {
@@ -25,6 +26,7 @@ const Index = () => {
+
)