Documentation

$import

Import JSON data at compile-time with zero runtime overhead.

Basic Usage

Import JSON files from the static/ directory:

data class User(val id: String, val name: String)

val users: List<User> = $import("fixtures/users.json")

$import embeds JSON at compile-time. The JSON file is parsed during transpilation and included directly in the generated Kotlin code. No runtime file I/O.

File Location

Place JSON files in the static/ directory:

myapp/
├── static/
│   ├── fixtures/
│   │   ├── users.json
│   │   └── products.json
│   └── config.json

Type Annotation Required

You must provide a type annotation so Whitehall knows how to deserialize:

// ✅ Good - explicit type
val users: List<User> = $import("fixtures/users.json")

// ❌ Bad - no type annotation
val users = $import("fixtures/users.json")

JSON Format

Array of Objects

// fixtures/users.json
[
  {"id": "1", "name": "Alice"},
  {"id": "2", "name": "Bob"}
]

// In code
data class User(val id: String, val name: String)
val users: List<User> = $import("fixtures/users.json")

Single Object

// config.json
{
  "api_url": "https://api.example.com",
  "timeout": 30
}

// In code
data class Config(val apiUrl: String, val timeout: Int)
val config: Config = $import("config.json")

Case Conversion

JSON keys are automatically converted from snake_case to camelCase:

// JSON: {"user_name": "Alice", "created_at": "2024-01-01"}
data class User(val userName: String, val createdAt: String)

Nested Objects

// fixtures/posts.json
[
  {
    "id": "1",
    "title": "Hello World",
    "author": {
      "name": "Alice",
      "email": "alice@example.com"
    }
  }
]

// In code
data class Author(val name: String, val email: String)
data class Post(val id: String, val title: String, val author: Author)

val posts: List<Post> = $import("fixtures/posts.json")

Use Cases

Seed Data

Include initial data for development or demos:

data class Product(val id: String, val name: String, val price: Double)
val products: List<Product> = $import("fixtures/products.json")

<LazyColumn>
  @for (product in products) {
    <ProductCard product={product} />
  }
</LazyColumn>

Configuration

Embed app configuration:

data class AppConfig(
  val apiUrl: String,
  val features: List<String>,
  val maxRetries: Int
)

val config: AppConfig = $import("config.json")

Test Fixtures

Use in tests for consistent test data:

val testUsers: List<User> = $import("fixtures/test-users.json")

Since $import happens at compile-time, changing the JSON file requires rebuilding. Use $fetch for data that changes at runtime.

See Also

  • $fetch - Runtime HTTP requests
  • $env - Environment variables