WARNING: This is still very much a pre-release library that's a work in progress. I make no guarantees that anything works correctly yet.
A TypeScript wrapper library around @humanwhocodes/crosspost that adds AI-powered content adaptation for multi-platform social media posting.
- π€ AI-Powered Content Adaptation: Automatically adapt your content for different social media platforms using LLM prompts
- π― Platform-Specific Optimization: Tailored prompts for Twitter, LinkedIn, Mastodon, and Bluesky
- π§ Flexible Configuration: TOML-based configuration for prompts and model parameters.
- π₯ Identity Mapping: Map custom user tokens to platform-specific handles
- π Purely Additive: Full passthrough of crosspost functionality (images, URLs, signals, etc.)
- π§ͺ Well-Tested: Comprehensive test coverage with TypeScript support
- URL-Aware Adaptation: Automatically detects URLs in your content and adjusts character counts and adaptation strategies accordingly.
- Content Validation: Ensures that generated content adheres to platform-specific character limits (e.g., Twitter, Bluesky, Mastodon).
bun add poster- Create a configuration file at
config/config.toml:
[twitter]
prompt = """
Adapt the following text for Twitter (X). Keep these guidelines in mind:
- Maximum 280 characters
- Make it engaging and conversational
- Use appropriate hashtags if relevant
- If images are attached, you can be more descriptive as the visuals will provide context
Text to adapt:
"""
temperature = 0.8
max_tokens = 280
top_p = 0.9
[linkedin]
prompt = """
Adapt the following text for LinkedIn. Keep these guidelines in mind:
- Professional and thoughtful tone
- Longer form content is acceptable and encouraged
- Use professional hashtags when relevant
- Focus on insights, learnings, or professional value
Text to adapt:
"""
temperature = 0.7
max_tokens = 1300
top_p = 0.9- Basic usage:
import { poster } from "poster";
await poster({
content: "Just shipped a new feature that improves user experience by 40%!",
strategyId: "twitter",
});The configuration file defines platform-specific prompts and model parameters. Each platform section should include:
prompt: Multi-line string containing instructions for the LLM- LLM settings like
temperature,max_tokens,top_p
Supported platforms match crosspost strategies:
twitter- Twitter/Xlinkedin- LinkedInmastodon- Mastodonbluesky- Bluesky
A configuration file for commit message generation using the marclove/llmc node library.
Optional file for mapping custom user tokens to platform-specific handles:
["@JaneDev"]
twitter = "JaneDev_X"
linkedin = "jane-developer"
mastodon = "jane@mastodon.social"
["@CompanyAccount"]
twitter = "company_official"
linkedin = "company-inc"Usage with identity mapping:
await poster({
content: "Thanks @JaneDev for the amazing collaboration!",
strategyId: "twitter",
});
// "@JaneDev" gets replaced with "JaneDev_X" before LLM processingImages must be provided as Uint8Array data, not URLs. Convert image URLs to
binary data first:
import { poster } from "poster";
// First, fetch and convert image to Uint8Array
const response = await fetch("https://example.com/image.jpg");
const imageData = new Uint8Array(await response.arrayBuffer());
await poster({
content: "Check out our latest product update!",
strategyId: "twitter",
postOptions: {
images: [
{ data: imageData, alt: "Product screenshot" },
],
},
});await poster({
content: "Custom configuration example",
strategyId: "linkedin",
configPath: "custom/my-config.toml",
identitiesPath: "custom/my-identities.toml",
});const controller = new AbortController();
await poster({
content: "This post can be cancelled",
strategyId: "twitter",
postOptions: {
signal: controller.signal,
},
});Main function that adapts content and posts to social media platforms.
Parameters:
options.content(string): The text content to adapt and postoptions.strategyId(string): The platform strategy to use (twitter, linkedin, etc.)options.configPath(string, optional): Path to config.toml file (default: "config/config.toml")options.identitiesPath(string, optional): Path to identities.toml file (default: "config/identities.toml")options.postOptions(PostOptions, optional): Additional crosspost options (images, signal, etc.)
Returns: Promise that resolves when the post is successful
Throws: PosterError if any step fails
The library throws PosterError for all failure cases:
import { poster, PosterError } from "poster";
try {
await poster({
content: "Hello world!",
strategyId: "twitter",
});
} catch (error) {
if (error instanceof PosterError) {
console.error("Posting failed:", error.message);
console.error("Caused by:", error.cause);
}
}bun install# Run tests once
bun run test
# Run tests in watch mode
bun run test:watchSee config/config.example.toml for a complete configuration example with all
supported platforms and detailed prompt guidelines.
- Load Configuration: Reads platform-specific prompts and hyperparameters from TOML files
- Identity Mapping: Optionally replaces custom user tokens with platform-specific handles
- LLM Adaptation: Uses Vercel AI SDK to adapt content using platform-specific prompts
- Crosspost Integration: Passes adapted content and all options to the crosspost library
- Post: Content is posted to the specified platform
- Bun 1.2.17+ (or Node.js 18+)
- TypeScript 5+
- Valid API keys for your chosen LLM provider (OpenAI, Anthropic, etc.)
- Valid API credentials for target social media platforms
BSD 3-Clause License