'use client' import { Button } from '@/components/button' import { Container } from '@/components/container' import { Footer } from '@/components/footer' import { Gradient, GradientBackground } from '@/components/gradient' import { Link } from '@/components/link' import { Mark } from '@/components/logo' import { Navbar } from '@/components/navbar' import { Heading, Lead, Subheading } from '@/components/text' import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react' import { CheckIcon, ChevronUpDownIcon, MinusIcon, } from '@heroicons/react/16/solid' import { useSearchParams } from 'next/navigation' import type React from 'react' function DropLogo() { return (
) } function GameVaultLogo() { return (
GameVault Logo GameVault
) } function GameVaultPlus() { return (
GameVault+ icon GameVault+
) } function ComingSoon() { return (
coming soon™
) } function RomMLogo() { return (
RomM icon RomM workmark
) } const projects: Array<{ name: string slug: string logo: () => React.JSX.Element description: string href: string highlights: Array<{ description: string; disabled?: boolean; paid?: boolean }> features: { [key: string]: { [key: string]: number | string | boolean | (() => React.JSX.Element) } } }> = [ { name: 'Drop OSS' as const, slug: 'drop', logo: DropLogo, description: 'An open-source and free self-hosted Steam alternative.', href: '/', highlights: [ { description: 'First-class Linux support' }, { description: 'Game versioning' }, { description: 'Multiple metadata sources' }, { description: 'Cloud saves & playtime tracking', disabled: true }, { description: 'Overlay network for Steam-like play together', disabled: true, }, ], features: { Library: { 'Multiple libraries': true, 'Versioned layout': true, 'Non-versioned layout': true, 'Installer/setup games': true, 'Portable games': true, 'Archives support': 'All 7-zip formats', }, Metadata: { 'Additional with plugins': false, IGDB: true, GiantBomb: true, PCGamingWiki: true, Manual: true, Steam: true, }, Clients: { Windows: true, Linux: true, macOS: true, Android: ComingSoon, }, Authentication: { Simple: true, SSO: true, }, Cloud: { 'Cloud saves': ComingSoon, 'Steamworks-compatible networking': ComingSoon, 'Dedicated server discovery': ComingSoon, }, 'Client Features': { 'Proton compatible for Linux': true, 'Multi-server': ComingSoon, 'In-game overlay': ComingSoon, }, Additional: { 'User collections': true, 'Server news': true, }, }, }, { name: 'GameVault' as const, slug: 'gamevault', logo: GameVaultLogo, description: 'A source-available, mature Steam-like experience for your home server.', href: 'https://gamevau.lt/', highlights: [ { description: 'Native Windows app' }, { description: 'Published on Microsoft Store' }, { description: 'Playtime tracking' }, { description: 'Cloud saves', paid: true }, { description: 'Third-party integrations', paid: true }, ], features: { Library: { 'Multiple libraries': 'Using Docker volumes or symlinks', 'Automatic import': true, 'Non-versioned layout': true, 'Installer/setup games': true, 'Portable games': true, 'Archives support': 'All 7-zip formats', }, Metadata: { 'Additional with plugins': true, IGDB: true, Manual: true, VNDB: 'Community plugin', }, Clients: { Windows: true, Linux: true, macOS: true, }, Authentication: { Simple: true, SSO: true, }, Cloud: { 'Cloud saves': GameVaultPlus, }, 'Client Features': { 'Multi-server': true, Theming: GameVaultPlus, 'Multi-profile usage': GameVaultPlus, 'Playnite integration': GameVaultPlus, 'Steam integration': GameVaultPlus, 'Discord integration': GameVaultPlus, }, Additional: { 'Parental controls': true, 'Server news': true, }, }, }, { name: 'RomM' as const, slug: 'romm', logo: RomMLogo, description: 'An open-source, self-hosted rom manager, with built-in large emulator support.', href: 'https://romm.app/', highlights: [ { description: '400+ supported platforms' }, { description: 'Web-based (EmulatorJS) emulation' }, { description: 'Multiple metadata sources' }, { description: 'Android app' }, { description: 'Cloud sync', disabled: true }, ], features: { Library: { 'Non-versioned layout': true, 'Automatic import': true, 'Archives support': 'All 7-zip formats', }, Metadata: { IGDB: true, Hasheous: true, SteamGridDB: true, Retroachievements: true, PlayMatch: true, ScreenScraper: true, LaunchBox: true, }, Clients: { Browser: true, Android: true, muOS: true, }, 'Client Features': { 'Playnite integration': true, }, Authentication: { Simple: true, SSO: true, }, Cloud: { 'Cloud saves': ComingSoon, }, }, }, ] function Header() { return ( What's the{' '} git diff ? A breakdown between the different projects available to you, put together by the Drop OSS project. Last updated 19-01-2026 ) } function PricingCards() { return (
{projects.map((tier, tierIndex) => ( ))}
) } function PricingCard({ tier }: { tier: (typeof projects)[number] }) { return (
{tier.logo()}
{tier.name}

{tier.description}

Key features:

    {tier.highlights.map((props, featureIndex) => ( ))}
) } function PricingTable({ selectedTier: selectedProject, }: { selectedTier: (typeof projects)[number] }) { function onlyUnique(value: T, index: number, array: Array) { return array.indexOf(value) === index } const sections = projects .map((e) => Object.keys(e.features)) .flat() .filter(onlyUnique) const features: { [key: string]: string[] } = {} for (const section of sections) { const uniqueFeatures = projects .filter((e) => e.features[section]) .map((e) => Object.keys(e.features[section])) .flat() .filter(onlyUnique) features[section] = uniqueFeatures } return ( ))} {projects.map((tier) => ( ))} {sections.map((section) => ( {features[section].map((name) => ( {projects.map((project) => { let value = project.features[section]?.[name] return ( ) })} ))} ))}
Project comparison
{projects.map((project) => ( {project.name}
{selectedProject.name} {projects.map((tier) => ( {tier.name} ))}
Get started
{section}
{name} {typeof value === 'function' ? ( <>{value()} ) : value === true ? ( <> Included in {project.name} ) : value === false || value === undefined ? ( <> Not included in {project.name} ) : (
{value}
)}
) } function FeatureItem({ description, disabled = false, paid = false, }: { description: string disabled?: boolean paid?: boolean }) { return (
  • {disabled && Coming soon:} {description} {disabled && ( coming soon™ )} {paid && }
  • ) } function PlusIcon(props: React.ComponentPropsWithoutRef<'svg'>) { return ( ) } export default function Pricing() { let params = useSearchParams() let tier = typeof params.get('tier') === 'string' ? projects.find(({ slug }) => slug === params.get('tier'))! : projects[0] return (
    ) }