A comprehensive example of building a federated server application using Fedify with SvelteKit. This sample demonstrates how to create an ActivityPub-compatible federated social media server that can interact with other federated platforms like Mastodon, Pleroma, and other ActivityPub implementations.
- ActivityPub Protocol Support: Full implementation of ActivityPub for federated social networking
- Actor System: User profile management with cryptographic key pairs
- Follow/Unfollow: Complete follow relationship handling with Accept/Undo activities
- Inbox Processing: Real-time activity processing from federated instances
- Modern UI: Built with SvelteKit and Tailwind CSS
- TypeScript: Full type safety throughout the application
Before you begin, ensure you have the following installed:
- Node.js (version 18 or higher)
- npm or yarn package manager
- Git for version control
git clone https://github.com/fedify-dev/fedify.git
cd fedify/examples/sveltekit-samplepnpm installThe application uses in-memory storage by default, so no additional database setup is required for development. However, for production deployment, you may want to configure external storage.
pnpm devThe development server will start on http://localhost:5173 by default.
The federation setup is configured in src/lib/federation.ts:
const federation = createFederation({
kv: new MemoryKvStore(), // In-memory storage for development
});-
Storage Backend:
- Development:
MemoryKvStore()(data lost on restart) - Production: Consider using persistent storage solutions
- Development:
-
Actor Identifier:
- Default:
"demo" - Modify the
IDENTIFIERconstant to change the demo user
- Default:
-
Demo Actor Profile:
- Name: “Fedify Demo”
- Summary: “This is a Fedify Demo account.”
- Icon:
/demo-profile.png
The application includes support for proxy headers via x-forwarded-fetch.
This is configured in src/lib/handles.ts:
export const replaceHost: Handle = async ({ event, resolve }) => {
event.request = await getXForwardedRequest(event.request);
return resolve(event);
};This is useful when deploying behind reverse proxies or using tunneling services like ngrok.
But if you don't use proxy or tunnel, the handle is unnecessary.
-
Start the development server:
pnpm dev
-
Access the demo user profile:
curl http://localhost:5173/users/demo -
The ActivityPub actor endpoint is available at:
curl -H "Accept: application/activity+json" http://localhost:5173/users/demo
activitypub.academy is a platform for learning about the ActivityPub
protocol and its implementation.
To test federation with activitypub.academy:
-
Deploy the application to a public server or use a tunneling service:
# Using Fedify CLI to tunnel fedify tunnel 5173 -
From your
activitypub.academyaccount, search for and follow:@demo@6c10b40c63d9e1ce7da55667ef0ef8b4.serveo.net -
The application will automatically:
- Receive the follow request
- Send an Accept activity back
- Store the relationship
To create additional actors, modify src/lib/federation.ts:
// Add more identifiers
const IDENTIFIERS = ["demo", "alice", "bob"];
federation.setActorDispatcher(
"/users/{identifier}",
async (context, identifier) => {
if (!IDENTIFIERS.includes(identifier)) {
return null;
}
// ... actor creation logic
},
);The application logs activities to the console. Monitor the development console to see:
- Incoming follow requests
- Outgoing accept activities
- Undo operations
Extend the inbox listeners to handle additional ActivityPub activities:
federation
.setInboxListeners("/users/{identifier}/inbox", "/inbox")
.on(Follow, async (context, follow) => {
// Handle follow requests
})
.on(Undo, async (context, undo) => {
// Handle undo operations
})
.on(Like, async (context, like) => {
// Add custom like handling
});src/
├── app.css # Global styles
├── app.d.ts # TypeScript app declarations
├── app.html # HTML template
├── hooks.server.ts # Server-side hooks
├── lib/
│ ├── federation.ts # Main federation configuration
│ ├── fetch.ts # Fetch utilities
│ ├── handles.ts # Request handlers
│ ├── index.ts # Library exports
│ ├── store.ts # In-memory data storage
│ ├── types.ts # TypeScript type definitions
│ ├── assets/
│ │ └── favicon.svg # Favicon asset
│ └── components/
│ ├── Profile.svelte # Profile component
│ └── Spinner.svelte # Loading spinner component
└── routes/
├── +layout.svelte # Layout component
├── +page.server.ts # Home page server logic
├── +page.svelte # Home page
└── users/
└── [identifier]/
├── +page.server.ts # User profile server logic
├── +page.svelte # User profile page
└── posts/
├── +page.server.ts # User posts server logic
├── +page.svelte # User posts page
└── [id]/
├── +page.server.ts # Individual post server logic
└── +page.svelte # Individual post page
pnpm buildpnpm preview
- HTTPS Required: ActivityPub requires HTTPS in production
- Domain Configuration: Ensure proper domain setup for federation
- Storage: Replace
MemoryKvStorewith persistent storage - Environment Variables: Configure production-specific settings
# Build for production
pnpm build
# Preview the build
pnpm preview
# Or deploy to your preferred platform
# (Vercel, Netlify, Docker, etc.)This is a sample application demonstrating Fedify capabilities. Feel free to:
- Experiment with the code
- Add new features
- Fedify GitHub Repository
- Use as a starting point for your own federated applications
This sample application follows the same license as the main Fedify project.