Skip to main content

Build Faster with Production-Ready Components

Skip the boilerplate and focus on your app's unique features. Our battle-tested packages power many Flutter applications in production, giving you reliable AT Protocol and Bluesky integration from day one. Get comprehensive API coverage with atproto, bluesky, and bluesky_text for advanced text processing.

Write Confident Code with Complete Type Safety

Eliminate runtime crashes before they happen. Every package is 100% null safe, leveraging Dart's robust type system to catch errors at compile time. Your app will never crash from null pointer exceptions, giving you confidence in production deployments.

Integrate Effortlessly into Your Flutter Workflow

Start building immediately with Flutter-native design patterns. Our packages follow Dart conventions you already know, enabling seamless integration without learning curves. Build powerful AT Protocol features even without deep protocol knowledge – we handle the complexity for you.

Deploy with Confidence Using Proven Stability

Ship reliable apps backed by comprehensive testing. Every release passes extensive unit and integration tests covering real-world scenarios. Our packages deliver consistent, high-quality performance that your users can depend on.

Complete AT Protocol Integration

Build AT Protocol and Bluesky applications with our comprehensive SDK featuring atproto and bluesky packages. The atproto package covers the complete com.atproto.* specification, while bluesky extends this foundation with full app.bsky.* support.

Focus on your app logic instead of protocol complexity. You don't need to understand XRPC internals or handle low-level communication – our packages abstract these details while maintaining full functionality.

Every API call is fully type-safe and completely null safe, enabling you to integrate seamlessly and confidently into any Dart or Flutter project.

Includes our comprehensive moderation API for implementing Bluesky content moderation without requiring deep knowledge of labeling systems.

//! Moderation Stuffs
final preferences = await bsky.actor.getPreferences();
final moderationPrefs = preferences.data.getModerationPrefs();
final labelDefs = await bsky.labeler.getLabelDefinitions(moderationPrefs);
final labelerHeaders = mod.getLabelerHeaders(moderationPrefs);

final moderationOpts = mod.ModerationOpts(
userDid: bsky.session!.did,
prefs: moderationPrefs,
labelDefs: labelDefs,
);

final timeline = await bsky.feed.getTimeline($headers: labelerHeaders);
for (final feed in timeline.data.feed) {
final record = FeedPostRecord.fromJson(feed.post.record);
final text = record.text.toLowerCase();

if (text.contains('bluesky')) {
await bsky.feed.like.create(
subject: RepoStrongRef(cid: feed.post.cid, uri: feed.post.uri),
);
}

final postModeration = mod.moderatePost(
mod.ModerationSubjectPost.postView(data: feed.post),
moderationOpts,
);

if (postModeration.getUI(mod.ModerationBehaviorContext.contentView).blur) {
// nsfw...?
}
}

Real-Time Data Streaming

Stream live AT Protocol events effortlessly with our Firehose API integration in atproto and bluesky. Monitor real-time activity across any Personal Data Server (PDS) to build analytics dashboards, content moderation tools, or automated bots that respond to network events.

For Bluesky applications, leverage the specialized RepoCommitAdaptor to filter and process only the events you care about. This targeted approach dramatically reduces processing overhead and accelerates development of real-time features.

final bsky = Bluesky.anonymous();
final subscription = await bsky.atproto.sync.subscribeRepos();

await for (final event in subscription.data.stream) {
final repos = const firehose.SyncSubscribeReposAdaptor().execute(event);

if (repos.isCommit) {
const firehose.RepoCommitHandler(
onCreateFeedPost: print,
onUpdateActorProfile: print,
onDeleteGraphFollow: print,
).execute(repos.commit!);
}
}

Intelligent Error Recovery

Handle network instability gracefully with automatic retry logic built into atproto and bluesky. Our packages intelligently detect and recover from temporary failures without manual intervention.

Network interruptions like TimeoutException are handled transparently, along with server errors returning 5xx status codes. Your app stays responsive even when the network doesn't cooperate.

The retry mechanism implements industry-standard Exponential Backoff with Jitter, balancing quick recovery with server-friendly request patterns that won't overwhelm struggling endpoints.

final retryConfig = RetryConfig(
maxAttempts: 10,
jitter: Jitter(maxInSeconds: 5, minInSeconds: 3),
onExecute: (event) => print(
'Retry after ${event.intervalInSeconds} seconds...'
'[${event.retryCount} times]',
),
);

final session = await createSession(
identifier: 'shinyakato.dev',
password: 'xxxxxxxx',
retryConfig: retryConfig,
);

final bsky = Bluesky.fromSession(session.data, retryConfig: retryConfig);

// Do retry if there are communication errors, etc
final timeline = await bsky.feed.getTimeline();

Rich Text Made Simple

Transform plain text into rich Bluesky posts effortlessly with bluesky_text. Automatically detect and format mentions, links, hashtags, and markdown syntax while generating the required facets JSON structure behind the scenes.

Combine bluesky_text with bluesky to publish rich content without wrestling with complex text processing or facet generation. Focus on your content while we handle the technical formatting requirements.

Essential for any Bluesky application that handles user-generated content. bluesky_text eliminates the complexity of rich text processing in social applications.

import 'package:bluesky/app_bsky_richtext_facet.dart';
import 'package:bluesky/bluesky.dart';
import 'package:bluesky/atproto.dart';
import 'package:bluesky_text/bluesky_text.dart';

Future<void> main(List<String> args) async {
final session = await createSession(
identifier: 'shinyakato.dev',
password: 'xxxxxxxx',
);

final bsky = Bluesky.fromSession(session.data);

final text = BlueskyText(
'Hello, I am @shinyakato.dev! '
'wdyt about [this link](https://atprotodart.com)?',
linkConfig: const LinkConfig(excludeProtocol: true, enableShortening: true),
).format();

final facets = await text.entities.toFacets();

final strongRef = await bsky.feed.post.create(
text: text.value,
facets: facets.map(RichtextFacet.fromJson).toList(),
);
}