diff --git a/README.md b/README.md
index 9206f12..3c1d141 100644
--- a/README.md
+++ b/README.md
@@ -208,6 +208,10 @@ bun run check
Feature flags and self-hosting environment variables are documented in `.env.example` and `.env.docker.example`.
+## License
+
+OpenFrame is Fair Source, licensed under the [Functional Source License](https://fsl.software/) (FSL-1.1-ALv2). The full source code is publicly available, you can self-host it, and every release automatically becomes Apache 2.0 open source two years after its publication. See [LICENCE](LICENCE) for the full terms.
+
## Contributing
Contributions are welcome.
@@ -215,3 +219,4 @@ Contributions are welcome.
- Read [CONTRIBUTING.md](CONTRIBUTING.md) for workflow, conventions, and PR requirements.
- Use [SECURITY.md](SECURITY.md) for responsible vulnerability reporting.
- Follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) in all project interactions.
+- Contact: [info@open-frame.net](mailto:info@open-frame.net)
diff --git a/app/api/settings/notifications/route.ts b/app/api/settings/notifications/route.ts
index 5021c9b..0fbb918 100644
--- a/app/api/settings/notifications/route.ts
+++ b/app/api/settings/notifications/route.ts
@@ -193,7 +193,7 @@ export async function POST(request: NextRequest) {
const fromAddress =
process.env.SMTP_FROM ||
process.env.EMAIL_FROM ||
- 'OpenFrame ';
+ 'OpenFrame ';
try {
await transporter.sendMail({
diff --git a/app/terms/page.tsx b/app/terms/page.tsx
index 9679515..b276b49 100644
--- a/app/terms/page.tsx
+++ b/app/terms/page.tsx
@@ -150,7 +150,8 @@ export default function TermsOfServicePage() {
Interfere with or disrupt the integrity or performance of the Service.
Reverse engineer, decompile, or attempt to extract the source code of the Service
- (except where permitted by applicable open-source licenses).
+ (except where permitted by the applicable source license, such as the Functional
+ Source License covering the platform code).
Use the Service to send spam or unsolicited communications.
@@ -174,8 +175,11 @@ export default function TermsOfServicePage() {
intellectual property laws.
- The core platform code is made available as open-source software; please refer to the
- applicable license in the GitHub repository for details on permitted use.
+ The core platform code is made available under the Functional Source License
+ (FSL-1.1-ALv2): the source code is publicly available and may be self-hosted, and
+ each release becomes available under the Apache 2.0 license two years after its
+ publication. Please refer to the license in the GitHub repository for details on
+ permitted use.
diff --git a/components/LandingPage.tsx b/components/LandingPage.tsx
index b97b21b..9757239 100644
--- a/components/LandingPage.tsx
+++ b/components/LandingPage.tsx
@@ -234,14 +234,14 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) {
- Open Source Video Review
+ Fair Source Video Review
- Cut Video Approval Time in Half.
+ Get Client Sign-off From One Link.
Stop Chasing Timecodes.
@@ -249,27 +249,35 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) {
data-hero-copy
className="mx-auto max-w-2xl text-base text-muted-foreground md:text-xl"
>
- OpenFrame puts comments, voice notes, and annotations on a single timeline so clients
- say "yes" faster and your team stops guessing.
+ Hosted video review for editors, agencies, and small studios. Comments, voice notes,
+ and annotations land on one timeline — clients review in the browser, no account
+ needed.
@@ -644,70 +652,33 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) {
className="text-3xl font-semibold md:text-5xl text-foreground"
style={{ fontFamily: 'monospace', letterSpacing: '-0.02em' }}
>
- Deploy it yourself - or let us run it for you.
+ Let us run it for you - or deploy it yourself.
- {/* Card 1: Open Source */}
-
-
-
- Open Source (Self-hosted)
-
-
-
-
- Free
-
-
- For teams who want full control and can run their own infrastructure.
-
-
-
- -
-
- Full codebase access
-
- -
-
- Self-hosted infrastructure control
-
- -
-
- Manual update cadence
-
-
-
-
- View on GitHub
-
-
-
- {/* Card 2: Hosted Cloud */}
+ {/* Card 1: Hosted Cloud (recommended) */}
+
+ Recommended
+
- Best for teams who want zero setup.
+ Zero setup. Flat pricing, no per-seat fees.
Hosted Cloud
-
+
$10
/ month
+
+ Starts with a 7-day free trial. Cancel anytime.
+
-
@@ -751,10 +722,63 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) {
href={hostedCtaHref}
className="mt-auto group relative isolate inline-flex h-12 w-full items-center justify-center overflow-hidden bg-[#06b6d4] font-medium text-black transition-colors hover:bg-[#06b6d4]/90 text-sm"
>
- Start free
+ Start free trial
+ {/* Card 2: Fair Source (Self-hosted) */}
+
+
+
+ Fair Source (Self-hosted)
+
+
+
+
+ Free
+
+
+ For teams who want full control and can run their own infrastructure. Licensed
+ under the{' '}
+
+ Functional Source License
+
+ .
+
+
+
+ -
+
+ Full source code — read it, audit it
+
+ -
+
+ Self-host on your own infrastructure
+
+ -
+
+ Every release becomes Apache 2.0 open source after two years
+
+
+
+
+ View on GitHub
+
+
+
{/* Card 3: Studio & Agency */}
Contact us
@@ -823,7 +847,15 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) {
},
{
q: 'Can I self-host?',
- a: 'Yes. The core is open-source and self-hostable. Hosted Cloud is for teams who want zero setup.',
+ a: 'Yes. The full source code is public and ships with a Docker setup for self-hosting. Hosted Cloud is for teams who want zero setup.',
+ },
+ {
+ q: 'Is OpenFrame open source?',
+ a: 'OpenFrame is Fair Source, licensed under the Functional Source License (FSL). You can read and audit the full source code and self-host it, and every release automatically becomes Apache 2.0 open source two years after publication.',
+ },
+ {
+ q: 'Is there a free trial?',
+ a: 'Yes. Hosted Cloud starts with a 7-day free trial. After that it is a flat $10/mo — no per-seat or per-client fees.',
},
{
q: 'How is this different from sending a Google Drive link?',
@@ -874,7 +906,7 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) {
href={hostedCtaHref}
className="group relative isolate inline-flex h-12 min-w-max items-center justify-center overflow-hidden border border-primary bg-primary px-10 text-sm font-medium whitespace-nowrap text-primary-foreground transition-transform duration-300 hover:scale-[1.02] md:min-w-[240px]"
>
- Start free
+ Start free trial
diff --git a/lib/email-verification.ts b/lib/email-verification.ts
index 1944afb..9c0d5b1 100644
--- a/lib/email-verification.ts
+++ b/lib/email-verification.ts
@@ -111,7 +111,7 @@ export async function sendVerificationEmail(email: string, token: string): Promi
const verifyUrl = `${baseUrl}/api/auth/verify-email?token=${encodeURIComponent(token)}`;
const from =
- process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame
';
+ process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame ';
const html = brandedEmailTemplate(
`
diff --git a/lib/invitations.ts b/lib/invitations.ts
index 05df144..d35ebdc 100644
--- a/lib/invitations.ts
+++ b/lib/invitations.ts
@@ -68,7 +68,7 @@ export async function sendInvitationEmail(input: {
}
const fromAddress =
- process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame ';
+ process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame ';
const subject = `[OpenFrame] You were invited to a ${scopeLabel(input.scope)}: ${input.targetName}`;
const html = invitationEmailTemplate({
inviterName: input.inviterName,
diff --git a/lib/marketing/comparison-pages.ts b/lib/marketing/comparison-pages.ts
index a94cd6e..22d5927 100644
--- a/lib/marketing/comparison-pages.ts
+++ b/lib/marketing/comparison-pages.ts
@@ -202,7 +202,7 @@ export const comparisonPages: ComparisonPageDefinition[] = [
title: 'Frame.io Alternative for Small Teams',
metaDescription:
'Compare OpenFrame vs Frame.io for freelancers and small teams. Get timestamped review, approvals, guest links, and self-hosting without per-seat enterprise pricing.',
- keywords: ['frame.io alternative', 'frame io alternative', 'open source frame.io alternative'],
+ keywords: ['frame.io alternative', 'frame io alternative', 'fair source frame.io alternative'],
headline: 'Frame.io power without the enterprise bill',
subheadline:
'Frame.io is the industry standard for large post teams. OpenFrame gives freelancers and small studios the review workflow they actually need: one link, one timeline, clear approvals, and optional self-hosting.',
@@ -249,7 +249,7 @@ export const comparisonPages: ComparisonPageDefinition[] = [
keywords: [
'self hosted frame.io alternative',
'self-hosted video review',
- 'open source video review',
+ 'fair source video review',
],
eyebrow: 'Self-hosted review',
headline: 'Keep client footage on your infrastructure',
@@ -270,7 +270,7 @@ export const comparisonPages: ComparisonPageDefinition[] = [
bestForOpenFrame: [
'Teams with Docker ops capacity',
'Privacy-sensitive client work',
- 'Studios comparing Frame.io to open/fair-source options',
+ 'Studios comparing Frame.io to fair-source options',
],
bestForCompetitor: [
'Teams needing Adobe enterprise integrations out of the box',
@@ -297,7 +297,7 @@ export const comparisonPages: ComparisonPageDefinition[] = [
{ label: 'Version compare', openframe: 'yes', competitor: 'yes' },
{ label: 'Enterprise DRM / SSO', openframe: 'no', competitor: 'yes' },
{ label: 'Adobe NLE integrations', openframe: 'no', competitor: 'yes' },
- { label: 'Open/fair-source codebase', openframe: 'yes', competitor: 'no' },
+ { label: 'Fair-source codebase', openframe: 'yes', competitor: 'no' },
],
pricingRows: [
{ label: 'Self-hosted software cost', openframe: 'Free', competitor: 'Not available' },
diff --git a/lib/marketing/comparison-sources.ts b/lib/marketing/comparison-sources.ts
index 5078930..bab4a65 100644
--- a/lib/marketing/comparison-sources.ts
+++ b/lib/marketing/comparison-sources.ts
@@ -565,7 +565,7 @@ export const openFrameProfile = {
],
bestFor: [
'Freelancers and small teams shipping client cuts',
- 'Studios that want open/fair-source and optional self-hosting',
+ 'Studios that want fair-source licensing and optional self-hosting',
'Teams tired of vague email and WhatsApp feedback',
],
};
diff --git a/lib/notifications.ts b/lib/notifications.ts
index b305cdb..2f270a4 100644
--- a/lib/notifications.ts
+++ b/lib/notifications.ts
@@ -84,7 +84,7 @@ function createSmtpTransport() {
async function sendEmail(to: string, subject: string, html: string): Promise {
const transporter = createSmtpTransport();
const fromAddress =
- process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame ';
+ process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame ';
if (!transporter) {
console.warn('SMTP not configured — skipping email notification');
diff --git a/lib/seo.ts b/lib/seo.ts
index df5b137..026cbe6 100644
--- a/lib/seo.ts
+++ b/lib/seo.ts
@@ -1,4 +1,4 @@
-const FALLBACK_SITE_URL = 'https://openframe.net';
+const FALLBACK_SITE_URL = 'https://open-frame.net';
function normalizeSiteUrl(rawUrl: string | undefined): string {
if (!rawUrl) {
@@ -26,11 +26,12 @@ export function getSiteUrl(): string {
export const seoConfig = {
name: 'OpenFrame',
- title: 'Open Source Video Review Platform',
+ title: 'Fair Source Video Review Platform',
description:
- 'OpenFrame is an open source video review platform for collecting timestamped feedback with text and voice comments.',
+ 'OpenFrame is a fair source video review platform for collecting timestamped feedback with text and voice comments.',
keywords: [
- 'open source video review platform',
+ 'fair source video review platform',
+ 'video review platform',
'video review tool',
'timestamped video feedback',
'video collaboration',