krate-kmp

Enterprise-grade, type-safe filesystem API with operator-based paths and rich path utilities; coroutine-backed suspend operations for read/write/copy/move/delete/list, Compose-first integration and high performance.

Android
JVM
iOS
Wasm
JS
GitHub stars0
Authorssitharaj88
Dependents0
LicenseApache License 2.0
Creation date10 months ago

Last activity10 months ago
Latest release1.0.0 (10 months ago)

📦 Krate-KMP

Maven Central Kotlin License

Enterprise-grade File System Library for Kotlin Multiplatform

A unified, type-safe file system API that works seamlessly across Android, iOS, Desktop, and Web.

✨ Features

  • 🔒 Type-Safe Paths - No more string path errors with KratePath
  • ⚡ High Performance - Uses modern platform APIs (java.nio, OPFS)
  • 📱 Multi-Platform - Android, iOS, Desktop, Web (JS/WASM)
  • 🧩 Compose-First - rememberKrate() for seamless integration
  • 🔄 Coroutine-Based - Fully async with suspend functions
  • 📂 Complete Operations - Read, write, copy, move, delete, list

📋 Platform Support

Platform Backend Status
Android java.nio.file / java.io.File ✅ Full Support
iOS FileManager / Foundation ✅ Full Support
Desktop (JVM) java.nio.file ✅ Full Support
Browser (JS) Origin Private File System (OPFS) ✅ Full Support
Browser (WASM) In-Memory Storage ✅ Basic Support

📦 Installation

Add the dependency to your build.gradle.kts:

// Common
implementation("in.sitharaj.krate:krate:1.0.0")

// Or platform-specific
implementation("in.sitharaj.krate:krate-android:1.0.0")
implementation("in.sitharaj.krate:krate-iosarm64:1.0.0")
implementation("in.sitharaj.krate:krate-desktop:1.0.0")
implementation("in.sitharaj.krate:krate-js:1.0.0")

🚀 Quick Start

Basic Usage

@Composable
fun FileManagerScreen() {
    val krate = rememberKrate()
    val scope = rememberCoroutineScope()
    
    Button(onClick = {
        scope.launch {
            // Write a file
            val path = KrateLocation.documents / "notes" / "hello.txt"
            krate.writeText(path, "Hello, Krate!")
            
            // Read it back
            val content = krate.readText(path)
            println(content) // "Hello, Krate!"
            
            // List directory
            val files = krate.list(KrateLocation.documents)
            files.forEach { entry ->
                when (entry) {
                    is KrateEntry.File -> println("📄 ${entry.name} (${entry.size} bytes)")
                    is KrateEntry.Directory -> println("📁 ${entry.name}")
                }
            }
        }
    }) {
        Text("Demo")
    }
}

Type-Safe Paths

// Create paths using the / operator
val path = KrateLocation.documents / "projects" / "myapp" / "config.json"

// Path properties
path.name        // "config.json"
path.extension   // "json"
path.parent      // documents/projects/myapp

// Sibling path
val backup = path.sibling("config.backup.json")

Platform Locations

// App-private storage (safe for sensitive data)
KrateLocation.appData

// Cache directory (may be cleared by system)
KrateLocation.cache

// User documents (accessible on some platforms)
KrateLocation.documents

// Temporary directory
KrateLocation.temp

📖 API Reference

Read Operations

// Read as bytes
val bytes: ByteArray = krate.read(path)

// Read as text
val text: String = krate.readText(path)

// Safe read (returns null if not found)
val bytesOrNull: ByteArray? = krate.readOrNull(path)

Write Operations

// Write bytes
krate.write(path, byteArray)

// Write text
krate.writeText(path, "Hello, World!")

// Append to file
krate.writeText(path, "\nNew line", append = true)

File Operations

// Check existence
val exists: Boolean = krate.exists(path)

// Delete file
val deleted: Boolean = krate.delete(path)

// Copy file
krate.copy(source, destination, overwrite = true)

// Move file
krate.move(source, destination, overwrite = true)

// Get metadata
val metadata: FileMetadata = krate.metadata(path)

Directory Operations

// Create directory
krate.createDirectory(path)

// List contents
val entries: List<KrateEntry> = krate.list(path)

// Delete directory
krate.deleteDirectory(path, recursive = true)

🏗️ Architecture

┌─────────────────────────────────────────────────────────────┐
│                      Krate API (Common)                      │
│  ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌───────────────┐  │
│  │  read()  │ │ write()  │ │  copy()   │ │    list()     │  │
│  └──────────┘ └──────────┘ └───────────┘ └───────────────┘  │
├─────────────────────────────────────────────────────────────┤
│  Android       │  iOS           │  Desktop    │  Browser    │
│  ──────────    │  ────────────  │  ─────────  │  ────────   │
│  java.nio.file │  FileManager   │  java.nio   │  OPFS       │
│  SAF support   │  Foundation    │  Files API  │  Modern API │
└─────────────────────────────────────────────────────────────┘

🔧 Advanced Usage

Error Handling

try {
    val content = krate.read(path)
} catch (e: KrateException) {
    when (e.error) {
        KrateError.FILE_NOT_FOUND -> println("File doesn't exist")
        KrateError.PERMISSION_DENIED -> println("No permission")
        KrateError.IO_ERROR -> println("I/O error occurred")
        else -> println("Error: ${e.error}")
    }
}

Result-Based API (Coming Soon)

when (val result = krate.readResult(path)) {
    is KrateResult.Success -> process(result.value)
    is KrateResult.Failure -> handleError(result.error)
}

📄 License

Copyright 2024 Sitharaj Seenivasan

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

🔗 Links

Android
JVM
iOS
Wasm
JS
GitHub stars0
Authorssitharaj88
Dependents0
LicenseApache License 2.0
Creation date10 months ago

Last activity10 months ago
Latest release1.0.0 (10 months ago)

📦 Krate-KMP

Maven Central Kotlin License

Enterprise-grade File System Library for Kotlin Multiplatform

A unified, type-safe file system API that works seamlessly across Android, iOS, Desktop, and Web.

✨ Features

  • 🔒 Type-Safe Paths - No more string path errors with KratePath
  • ⚡ High Performance - Uses modern platform APIs (java.nio, OPFS)
  • 📱 Multi-Platform - Android, iOS, Desktop, Web (JS/WASM)
  • 🧩 Compose-First - rememberKrate() for seamless integration
  • 🔄 Coroutine-Based - Fully async with suspend functions
  • 📂 Complete Operations - Read, write, copy, move, delete, list

📋 Platform Support

Platform Backend Status
Android java.nio.file / java.io.File ✅ Full Support
iOS FileManager / Foundation ✅ Full Support
Desktop (JVM) java.nio.file ✅ Full Support
Browser (JS) Origin Private File System (OPFS) ✅ Full Support
Browser (WASM) In-Memory Storage ✅ Basic Support

📦 Installation

Add the dependency to your build.gradle.kts:

// Common
implementation("in.sitharaj.krate:krate:1.0.0")

// Or platform-specific
implementation("in.sitharaj.krate:krate-android:1.0.0")
implementation("in.sitharaj.krate:krate-iosarm64:1.0.0")
implementation("in.sitharaj.krate:krate-desktop:1.0.0")
implementation("in.sitharaj.krate:krate-js:1.0.0")

🚀 Quick Start

Basic Usage

@Composable
fun FileManagerScreen() {
    val krate = rememberKrate()
    val scope = rememberCoroutineScope()
    
    Button(onClick = {
        scope.launch {
            // Write a file
            val path = KrateLocation.documents / "notes" / "hello.txt"
            krate.writeText(path, "Hello, Krate!")
            
            // Read it back
            val content = krate.readText(path)
            println(content) // "Hello, Krate!"
            
            // List directory
            val files = krate.list(KrateLocation.documents)
            files.forEach { entry ->
                when (entry) {
                    is KrateEntry.File -> println("📄 ${entry.name} (${entry.size} bytes)")
                    is KrateEntry.Directory -> println("📁 ${entry.name}")
                }
            }
        }
    }) {
        Text("Demo")
    }
}

Type-Safe Paths

// Create paths using the / operator
val path = KrateLocation.documents / "projects" / "myapp" / "config.json"

// Path properties
path.name        // "config.json"
path.extension   // "json"
path.parent      // documents/projects/myapp

// Sibling path
val backup = path.sibling("config.backup.json")

Platform Locations

// App-private storage (safe for sensitive data)
KrateLocation.appData

// Cache directory (may be cleared by system)
KrateLocation.cache

// User documents (accessible on some platforms)
KrateLocation.documents

// Temporary directory
KrateLocation.temp

📖 API Reference

Read Operations

// Read as bytes
val bytes: ByteArray = krate.read(path)

// Read as text
val text: String = krate.readText(path)

// Safe read (returns null if not found)
val bytesOrNull: ByteArray? = krate.readOrNull(path)

Write Operations

// Write bytes
krate.write(path, byteArray)

// Write text
krate.writeText(path, "Hello, World!")

// Append to file
krate.writeText(path, "\nNew line", append = true)

File Operations

// Check existence
val exists: Boolean = krate.exists(path)

// Delete file
val deleted: Boolean = krate.delete(path)

// Copy file
krate.copy(source, destination, overwrite = true)

// Move file
krate.move(source, destination, overwrite = true)

// Get metadata
val metadata: FileMetadata = krate.metadata(path)

Directory Operations

// Create directory
krate.createDirectory(path)

// List contents
val entries: List<KrateEntry> = krate.list(path)

// Delete directory
krate.deleteDirectory(path, recursive = true)

🏗️ Architecture

┌─────────────────────────────────────────────────────────────┐
│                      Krate API (Common)                      │
│  ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌───────────────┐  │
│  │  read()  │ │ write()  │ │  copy()   │ │    list()     │  │
│  └──────────┘ └──────────┘ └───────────┘ └───────────────┘  │
├─────────────────────────────────────────────────────────────┤
│  Android       │  iOS           │  Desktop    │  Browser    │
│  ──────────    │  ────────────  │  ─────────  │  ────────   │
│  java.nio.file │  FileManager   │  java.nio   │  OPFS       │
│  SAF support   │  Foundation    │  Files API  │  Modern API │
└─────────────────────────────────────────────────────────────┘

🔧 Advanced Usage

Error Handling

try {
    val content = krate.read(path)
} catch (e: KrateException) {
    when (e.error) {
        KrateError.FILE_NOT_FOUND -> println("File doesn't exist")
        KrateError.PERMISSION_DENIED -> println("No permission")
        KrateError.IO_ERROR -> println("I/O error occurred")
        else -> println("Error: ${e.error}")
    }
}

Result-Based API (Coming Soon)

when (val result = krate.readResult(path)) {
    is KrateResult.Success -> process(result.value)
    is KrateResult.Failure -> handleError(result.error)
}

📄 License

Copyright 2024 Sitharaj Seenivasan

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

🔗 Links