| Crates.io | dioxus-cookie |
| lib.rs | dioxus-cookie |
| version | 0.1.0 |
| created_at | 2026-01-21 20:41:03.270208+00 |
| updated_at | 2026-01-21 20:41:03.270208+00 |
| description | Unified cookie storage for Dioxus fullstack apps that fills the gap in native platforms with keychain integration and encrypted file-vault fallback for simulators |
| homepage | |
| repository | https://github.com/rapporian/dioxus-cookie |
| max_upload_size | |
| id | 2060073 |
| size | 148,998 |
Unified cookie storage for Dioxus fullstack apps that fills the gap in native platforms. One interface for web, desktop, iOS, and Android—no platform-specific code, no #[cfg] blocks, no silent auth failures. Includes encrypted file-vault fallback for consistent simulator development.
Dioxus fullstack apps compile to multiple targets from one codebase, but cookie handling is fragmented:
| Platform | Cookie Mechanism | What Happens |
|---|---|---|
| Web (server) | HTTP Set-Cookie headers |
Works |
| Web (WASM) | document.cookie |
Works |
| Desktop | None | Cookies silently lost |
| iOS/Android | None | Cookies silently lost |
| iOS Simulator | Keychain blocked | Entitlement errors |
When your server function sets a session cookie, it works perfectly on web. But on desktop and mobile, that cookie vanishes into the void—your auth breaks with no error message.
dioxus-cookie bridges this gap with platform-appropriate storage:
document.cookie (standard web cookies)One API. All platforms. Your auth code stays clean.
1. Add to Cargo.toml:
[dependencies]
dioxus-cookie = { version = "0.1", features = ["server", "desktop"] }
2. Initialize before launch:
use dioxus_cookie as cookie;
fn main() {
cookie::init();
dioxus::launch(App);
}
3. Use in server functions:
use dioxus_cookie::{self as cookie, CookieOptions, SameSite};
use std::time::Duration;
#[server]
async fn login(credentials: Credentials) -> Result<User, ServerFnError> {
let user = authenticate(credentials).await?;
cookie::set("session", &user.token, &CookieOptions::default())?;
Ok(user)
}
#[server]
async fn logout() -> Result<(), ServerFnError> {
cookie::clear("session")?;
Ok(())
}
That's it. Cookies now work on web, desktop, iOS, and Android.
Enable features for all platforms your app targets. The correct backend is selected automatically at compile time based on the build target.
Typical fullstack app (web + desktop):
[dependencies]
dioxus-cookie = { version = "0.1", features = ["server", "desktop"] }
Fullstack app with mobile:
[dependencies]
dioxus-cookie = { version = "0.1", features = ["server", "desktop", "mobile"] }
iOS Simulator development (add mobile-sim for file-based fallback):
[dependencies]
dioxus-cookie = { version = "0.1", features = ["server", "mobile-sim"] }
When you run dx build or dx serve, the correct backend is selected automatically based on the build target:
| Build command | Backend used |
|---|---|
dx serve / dx build --platform web (server) |
HTTP headers (server feature) |
dx build --platform web (WASM client) |
document.cookie (no feature needed) |
dx build --platform desktop |
System keyring (desktop feature) |
dx build --platform ios |
iOS Keychain (mobile feature) |
dx build --platform android |
Android Keystore (mobile feature) |
You enable all the features your project needs in Cargo.toml, then each dx build target uses the appropriate backend.
| Feature | Description |
|---|---|
server |
Server-side cookie handling via HTTP headers |
desktop |
Desktop platforms with system keyring storage |
mobile |
iOS/Android with Keychain/Keystore storage |
mobile-sim |
Mobile + file fallback for iOS Simulator development |
file-store |
Encrypted file fallback (debug builds only, see Security) |
use dioxus_cookie::{self as cookie, CookieOptions, SameSite};
use std::time::Duration;
#[server]
async fn login(credentials: Credentials) -> Result<User, ServerFnError> {
let user = authenticate(credentials).await?;
// Simple: use secure defaults
cookie::set("session", &user.token, &CookieOptions::default())?;
// Or customize options
cookie::set("session", &user.token, &CookieOptions {
max_age: Some(Duration::from_secs(86400 * 7)), // 7 days
http_only: true,
secure: true,
same_site: SameSite::Strict,
path: "/".to_string(),
})?;
Ok(user)
}
use dioxus_cookie as cookie;
// Returns None for HttpOnly cookies (by design)
let preference = cookie::get("theme");
// List all accessible cookie names
let names = cookie::list_names();
use dioxus_cookie as cookie;
#[server]
async fn logout() -> Result<(), ServerFnError> {
cookie::clear("session")?;
Ok(())
}
CookieOptions::default() prioritizes security:
| Option | Default | Purpose |
|---|---|---|
http_only |
true |
Prevents JavaScript access |
secure |
true |
HTTPS only |
same_site |
Lax |
CSRF protection |
path |
"/" |
Available to all routes |
On native platforms, dioxus-cookie enforces HttpOnly the same way browsers do:
use dioxus_cookie as cookie;
cookie::get("session") // → None (HttpOnly blocked)
cookie::get_internal("session") // → Some(...) (internal use only)
HttpOnly cookies are still sent automatically with HTTP requests.
file-store feature)The file-store feature provides an encrypted file-based fallback for environments where the system keychain is unavailable:
| Environment | Why keychain fails |
|---|---|
| iOS Simulator | Missing keychain entitlements |
| Linux without D-Bus | No Secret Service available |
| CI/CD pipelines | No desktop session |
| Docker containers | No keychain access |
Security limitations:
Use mobile-sim (which includes file-store) for iOS Simulator development, or add file-store directly for other fallback scenarios.
┌─────────────────────────────────────────────────────┐
│ dioxus-cookie API │
│ get / set / clear / list_names │
└────────────────────────┬────────────────────────────┘
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ server │ │ native │ │ stubs │
│ module │ │ module │ │ module │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ HTTP │ │ System │ │ document │
│ Headers │ │ Keyring │ │ .cookie │
└───────────┘ └───────────┘ └───────────┘
| Function | Description |
|---|---|
init() |
Initialize the cookie system. Call before dioxus::launch(). |
get(name) |
Get a cookie value. Returns None for HttpOnly cookies. |
get_internal(name) |
Get a cookie bypassing HttpOnly (internal use). |
set(name, value, options) |
Set a cookie with the given options. |
clear(name) |
Delete a cookie. |
list_names() |
List all accessible cookie names. |
get_storage_type() |
Get the active storage backend. |
"No server context available"
Cookie operations that set HTTP headers must run inside #[server] functions.
Cookies not persisting on iOS Simulator
Use the mobile-sim feature. The simulator lacks keychain entitlements, so cookies fall back to encrypted file storage.
"GLOBAL_REQUEST_CLIENT already initialized"
Call cookie::init() before dioxus::launch().
get() returns None for a cookie that was set
The cookie is HttpOnly. This is intentional—use get_internal() only for session restoration.
MIT