What Is Apple Pkl?
In early 2024, Apple launched Pkl (pronounced “Pickle”), an innovative file format and programming language that will revolutionize configuration management. Pkl is the first formal language designed specifically for configuration data.
Pkl is flexible, secure, and provides built-in error detection features. It integrates with popular programming languages, with the ability to automatically generate code in the language of your choice, and also supports many popular Integrated Development Environments (IDEs).
Apple Pkl is open source, using the Apache 2.0 license. You can download it from the official GitHub repo.
This is part of a series of articles about configuration management.
In this article:
Key Features of Pkl
- Programmability: Pkl introduces conditions, loops, and functions within configuration files, transforming them from static documents into dynamic scripts.
- Scalability: Tailored for projects of any size, Pkl’s design ensures configurations remain manageable, regardless of the project’s complexity.
- Enhanced IDE Support: With auto-complete, error highlighting, and inline documentation, Pkl is designed to make configuration management a more integrated and less error-prone part of the development process.
Why Use Pkl?
Pkl is a versatile programming language that can manage a wide range of configuration-related data. Key use cases include:
- Infrastructure configuration: Any infrastructure component, including networks, servers, cloud services, and containers, can be configured with Pkl. The language can generate configuration files in multiple formats like XML, JSON, and YAML.
- Application configuration: Pkl can be useful for settings of customer facing elements like user interfaces, and also for backend features, such as preferences and internal software parameters. It can automatically produce configuration code in popular programming languages including Java, Kotlin, Swift, and Go.
- Environment setup: Pkl can be used to configure a variety of environments such as staging, production, testing, and development. It is also useful to generate artifacts such as claims, environment variables, and credentials.
In these use cases and others, Pkl is the high level language defining the configuration, and based on this definition, it can generate the configuration files or artifacts needed for low-level components.
Related content: Read our guide to misconfiguration
Tips From the Expert
In my experience, here are tips that can help you better manage configuration using Apple Pkl:
-
Use configuration templates for consistency across environments Leverage Pkl’s templating capabilities to create reusable configuration templates for different environments (development, testing, production). This ensures uniformity while reducing duplication and manual errors when setting up multiple environments.
-
Integrate Pkl with CI/CD pipelines for automated configuration Automate the evaluation of Pkl configuration files within your CI/CD pipelines to ensure consistent configurations across deployments. This can help catch configuration issues early in the development process and streamline environment setup.
-
Implement Pkl schemas for strict validation Even though schemas are optional, defining them adds benefits like automatic validation and error detection during development. This reduces the likelihood of configuration errors going unnoticed until runtime, especially in large and complex setups.
-
Use abstraction to minimize redundancy Take full advantage of Pkl’s abstraction features by defining reusable configuration blocks for commonly used elements (e.g., database setups, API configurations). This makes your configuration files easier to maintain and scales better as complexity grows.
-
Employ modular configuration for better maintainability Split large configuration files into smaller, manageable modules and use Pkl’s module importing features. This approach increases the clarity of your configurations and allows teams to work on specific configuration components independently.
Pkl Example
Here is a simple example shared in the Pkl documentation. Consider the following file with a set of key-value pairs. This is a valid .pkl file.
name = "Pkl: Configure your Systems in New Ways"
attendants = 100
isInteractive = true
amountLearned = 13.37
If you save this as example.pkl and run the command:
pkl eval /Users/me/tutorial/intro.pkl
Pkl returns the following output, indicating that it accepts and understands the content of the file:
name = "Pkl: Configure your Systems in New Ways"
attendants = 100
isInteractive = true
amountLearned = 13.37
Now, you can ask Pkl to produce a configuration file in any format you need. For example, to create a JSON file, you can run this command:
pkl eval -f json /Users/me/tutorial/intro.pkl
Pkl returns a JSON file containing your configuration:
{
"name": "Pkl: Configure your Systems in New Ways",
"attendants": 100,
"isInteractive": true,
"amountLearned": 13.37
}
Or you can run this command to generate a PropertyList format:
pkl eval -f plist /Users/me/tutorial/intro.pkl
Here is what Pkl comes up with:
name
Pkl: Configure your Systems in New Ways
attendants
100
isInteractive
amountLearned
13.37
Pkl Concepts
Pkl goes far beyond basic key-value pairs as we saw in the example. Let’s see how the language manages complex configurations with various structures and formats.
Abstraction
As configurations grow in size and complexity, their understanding and maintenance become increasingly challenging. Pkl can help reduce this complexity. It can define similar configuration elements by focusing on their unique attributes, create simplified forms of common configuration elements, and decouple configuration structure from actual configuration data.
In addition, the language can reduce configuration enumeration, allowing users to specify configuration in simple terms and automatically generate complex configuration syntax.
Evaluation and Rendering
Pkl code is structured into modules. Each module is represented by a file. Evaluating a module creates an in-memory data model similar to a JSON data model. If the evaluation is successful, the Pkl evaluator transforms the data model into meaningful representation, and provides status code zero. If it fails, it generates error messages, and returns a non-zero status code.
In Pkl, the process of transforming a data model into another useful representation is known as ‘rendering’ the model. Pkl provides renderers for several data formats, including JSON, Jsonnet, Java properties, Property Lists, XML, and YAML. You can support your own custom formats by creating a customized renderer in either Pkl or Java.
Immutability and Secure Isolation
All data within the Pkl system is immutable. Any data manipulation results in a new data value, while the original value remains intact. This makes it easier to work with and manage configurations, and avoids many possible errors.
In addition, Pkl was designed to prevent security threats like code and command injection. Pkl code evaluation occurs within a tightly controlled environment. Apart from a limited number of exceptions, the interaction of Pkl code with the environment is highly restricted.
According to the makers of Pkl, the severest consequence of flawed or malicious Pkl code could be the exhaustion of CPU and memory resources, which will eventually lead to the Pkl evaluator being terminated. Pkl is designed to ensure code cannot be used to manipulate other aspects of the system it runs on.
Module Importing
Modules in Pkl can use other modules by importing them. This makes it possible for a large module to be broken down into more manageable pieces, making it easier to maintain. Pkl uses a customizable security policy to ensure that the process of importing is efficient and secure.
Configuration Schemas
In Pkl, configuration is represented as structured data. Users can use this structure to create formal schemas of configuration. A schema is a group of classes that define configuration properties, such as default settings, types, and constraints.
Schemas are not mandatory in Pkl, and might require a bit more effort to define, but can provide multiple benefits. For example, they enable generating automated documentation, strict validation of configurations during the development lifecycle, and support for schema-aware tools like IDEs or code editors.
Templating
Pkl allows users to create templates for both individual objects and entire modules. These templates are like a mold that can be transformed into actual configurations. Users can start from a template, fill in the necessary information, and overriding default settings as required. The ability to share template modules can make configuration much easier to maintain and share across teams, organizations, and development communities.
Related content: Read our guide to configuration management in software engineering
Getting Started with Apple Pkl
The command-line interface (CLI) of Pkl is designed to evaluate Pkl modules, presenting the results either directly on the console or saving it in a file format.
Pkl Versions
As of the time of this writing, the Pkl CLI is available for several platforms:
- Native macOS application for amd64 architecture
- Native Linux application for amd64 architecture
- Native Linux app for aarch64 architecture
- Native Alpine Linux application for amd64
- Java-based application compatible with Java 8/11/14
The Pkl documentation recommends using native apps for macOS and Linux users, because they are faster to load and execute Pkl code. Those working on other platforms can use the Java application which has broad compatibility and smaller binary size.
It’s worth noting that both development and release versions of the Pkl CLI can be manually downloaded and installed.
Installing Pkl
We’ll cover how to install the Pkl native applications for macOS (amd64) and Linux (amd64). See the official documentation for other versions.
macOS native application (amd64)
Downloading the Pkl file using this command (adjust the version in the URL to the latest version):
curl -L -o Pkl https://github.com/apple/Pkl/releases/download/0.25.2/Pkl-macos-amd64
Give the downloaded file executable rights:
chmod +x Pkl
Run the program and confirm its version:
./Pkl --version
You should see the following output or similar, indicating Pkl is properly installed:
Pkl 0.25.2 (macOS, native)
Linux native application (amd64)
Note: The Linux version of Pkl relies on dynamic linkage with glibc and libstdc++.
Download the Pkl file using this command (adjust the version in the URL to the latest version):
curl -L -o Pkl https://github.com/apple/Pkl/releases/download/0.25.2/Pkl-linux-amd64
Modify the permissions of the file to make it executable:
chmod +x Pkl
Start the program and verify its version:
./Pkl --version
You should see output similar to this:
Pkl 0.25.2 (Linux, native)
How Can You Contribute to Apple Pkl?
As an open-source initiative, Apple Pkl invites developers, testers, and documentation writers to enhance its development. Here are some ways you can contribute:
- Star and fork the project: Begin by starring and forking the Apple Pkl repository on GitHub. This not only boosts the project’s visibility but also allows you to experiment with the codebase independently.
- Report bugs and suggest features: If you encounter any bugs or have ideas for new features, you can report them by creating an issue on GitHub. Make sure to follow the provided issue template and give detailed information to help the maintainers understand and address your report.
- Submit pull requests: You can contribute code to Apple Pkl by submitting pull requests. Whether you are fixing bugs, adding new features, improving documentation, or writing tests, your contributions are welcome. Ensure that you adhere to the code style and commit guidelines, and provide a clear description of your changes in the pull request.
- Share knowledge: Increase the project’s reach by writing blog posts, articles, tutorials, or reviews about Apple Pkl. Sharing your experiences and feedback on social media platforms, forums, and developer communities can help attract more users and contributors to the project.
Learn more in our detailed guide to Configuration-as-Code