| Crates.io | botanica |
| lib.rs | botanica |
| version | 0.1.0 |
| created_at | 2025-09-07 06:13:39.040162+00 |
| updated_at | 2025-09-07 06:13:39.040162+00 |
| description | Professional botanical cultivation database with AI-powered plant insights |
| homepage | |
| repository | https://github.com/Michael-A-Kuykendall/botanica |
| max_upload_size | |
| id | 1827859 |
| size | 180,428 |
Botanica will be free forever. No asterisks. No "free for now." No pivot to paid.
Botanica is a production-ready botanical database that provides type-safe taxonomic management, cultivation tracking, and AI-powered plant insights. It's designed to be the invisible infrastructure that botanical applications just work with.
| Feature | Botanica | Typical Solutions |
|---|---|---|
| Type Safety | Full Rust types 🏆 | Runtime errors |
| Performance | Native SQLite 🏆 | ORM overhead |
| Taxonomy | Scientific standard 🏆 | Ad-hoc schemas |
| AI Integration | Optional ContextLite 🏆 | None |
| Testing | 69 comprehensive tests 🏆 | Minimal |
| Memory Safety | Zero unsafe code 🏆 | Manual management |
BONUS: Optional AI integration provides intelligent plant care recommendations and species identification.
[dependencies]
botanica = "0.1"
tokio = { version = "1.0", features = ["full"] }
uuid = { version = "1.0", features = ["v4"] }
use botanica::{BotanicalDatabase, Species, Genus, Family};
use botanica::queries::{species, genus, family};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize database with migrations
let db = BotanicalDatabase::memory().await?;
db.migrate().await?;
// Create taxonomic hierarchy
let rosaceae = Family::new("Rosaceae".to_string(), "Juss.".to_string());
family::insert_family(db.pool(), &rosaceae).await?;
let rosa = Genus::new(rosaceae.id, "Rosa".to_string(), "L.".to_string());
genus::insert_genus(db.pool(), &rosa).await?;
let sweet_briar = Species::new(
rosa.id,
"rubiginosa".to_string(),
"L.".to_string(),
Some(1753),
Some("LC".to_string()) // Conservation status
);
species::insert_species(db.pool(), &sweet_briar).await?;
// Query the database
let families = family::get_families_by_name(db.pool(), "Rosaceae").await?;
println!("Found {} families", families.len());
Ok(())
}
#[cfg(feature = "contextlite")]
use botanica::contextlite::BotanicalContext;
// AI-powered plant recommendations
let context = BotanicalContext::new("your-workspace").await?;
let recommendations = context.get_plant_recommendations(
&species,
&cultivation_records,
"How should I care for this plant?"
).await?;
// All operations are async with comprehensive error handling
let result = species::get_species_by_id(db.pool(), species_id).await?;
match result {
Some(species) => println!("Found: {}", species.specific_epithet),
None => println!("Species not found"),
}
// Atomic operations with rollback on failure
let mut tx = db.pool().begin().await?;
family::insert_family(&mut tx, &family).await?;
genus::insert_genus(&mut tx, &genus).await?;
species::insert_species(&mut tx, &species).await?;
tx.commit().await?;
// Automatic schema management
let db = BotanicalDatabase::file("botanical.db").await?;
db.migrate().await?; // Creates/updates schema automatically
I built Botanica because botanical research deserves better than ad-hoc spreadsheets and fragile databases.
This is my commitment: Botanica stays MIT licensed, forever. If you want to support development, sponsor it. If you don't, just build something amazing with it.
Botanica saves researchers time and prevents data loss. If it's useful, consider sponsoring for $5/month — less than your morning coffee, infinitely more valuable for science.
| Metric | Botanica | Typical ORM Solutions |
|---|---|---|
| Query Speed | Native SQLite | ORM overhead |
| Memory Usage | Minimal | Heavy frameworks |
| Type Safety | Compile-time | Runtime discovery |
| Binary Size | Small | Large dependencies |
| Startup Time | Instant | Framework initialization |
// Taxonomic hierarchy
pub struct Family { id: Uuid, name: String, authority: String }
pub struct Genus { id: Uuid, family_id: Uuid, name: String, authority: String }
pub struct Species { id: Uuid, genus_id: Uuid, specific_epithet: String, /* ... */ }
// Cultivation tracking
pub struct CultivationRecord { /* environmental conditions, growth data */ }
pub enum GrowthStage { Seed, Seedling, Vegetative, Flowering, Fruiting, Dormant }
// Family operations
family::insert_family(pool, &family) -> Result<()>
family::get_family_by_id(pool, id) -> Result<Option<Family>>
family::get_families_by_name(pool, name) -> Result<Vec<Family>>
family::update_family(pool, &family) -> Result<()>
family::delete_family(pool, id) -> Result<()>
// Similar patterns for genus and species
genus::* and species::* operations
See our amazing sponsors who make Botanica possible! 🙏
Sponsorship Tiers:
Research Institutions: Need invoicing? Email michaelallenkuykendall@gmail.com
✅ Ready for production:
✅ Used by:
MIT License - forever and always.
Philosophy: Scientific data deserves scientific-grade tools. Botanica is botanical infrastructure.
Forever maintainer: Michael A. Kuykendall
Promise: This will never become a paid product
Mission: Making botanical data management bulletproof
"Every species matters. Every record counts. Every database should be reliable."