INI Tools
Parse, validate, and convert INI configuration files
Essential for Windows applications, legacy system configurations, and simple settings files. INI (Initialization) files are one of the oldest and simplest configuration formats, still widely used in Windows applications, game configurations, and embedded systems. Our tools help you parse, convert, and work with INI files across different platforms.
What is INI?
INI (Initialization) files are simple text-based configuration files that use a basic structure of sections, properties, and values. Introduced with MS-DOS and popularized by Windows 3.x, INI files remain relevant today due to their simplicity and human readability.
History & Creation
INI files were introduced with MS-DOS in the early 1980s and became widely used with Windows 3.0 (1990). The format was designed to be simple enough to edit with basic text editors while providing structure for configuration data. Though Microsoft later promoted the Windows Registry and XML, INI files persist due to their simplicity.
Where INI is Used
- Windows desktop applications
- Game configuration files
- PHP configuration (php.ini)
- Git configuration (.gitconfig)
- Desktop entry files (Linux .desktop)
- Embedded systems settings
- Legacy application configs
Benefits Over Other Formats
- vs Registry: Portable, human-readable, easy backup, no special tools needed
- vs XML: Much simpler syntax, smaller files, easier to edit manually
- vs JSON: Comments supported, more forgiving syntax, simpler for basic configs
- vs Database: No server required, plain text, version control friendly
INI Format Structure
[Sections]
Group related settings together. Section names are enclosed in square brackets.
key=value
Properties are simple key-value pairs. No quotes needed for string values.
; Comments
Comments start with semicolon (;) or hash (#). Some parsers support both.
Working with INI Files Across Systems
🪟 Windows
- Native API support
- Notepad for editing
- PowerShell Get-Content
- Many apps use INI
🐧 Linux
- crudini tool
- Python configparser
- sed/awk for parsing
- Used in .desktop files
🍎 macOS
- No native support
- Python configparser
- Third-party tools
- Less common usage
Convert INI ↔ JSON
Convert between INI and JSON formats
INI Format Examples & Best Practices
Despite its age, INI format remains popular due to its simplicity. Here are comprehensive examples showing various use cases and patterns.
Basic INI Structures
Simple Configuration File
Basic application settings with sections
; Application Configuration
[General]
AppName=My Application
Version=2.1.0
Language=en-US
Theme=dark
[Window]
Width=1280
Height=720
PositionX=100
PositionY=100
Maximized=false
Fullscreen=false
[Database]
Host=localhost
Port=5432
Database=myapp_db
Username=appuser
; Password should be stored securely, not in INI
ConnectionTimeout=30
[Logging]
Level=INFO
LogFile=app.log
MaxFileSize=10485760 ; 10MB in bytes
RotateCount=5
Game Configuration
Typical game settings file structure
; Game Settings - Last modified: 2024-01-20
[Graphics]
Resolution=1920x1080
Fullscreen=true
VSync=true
AntiAliasing=4x
TextureQuality=High
ShadowQuality=Medium
EffectsQuality=High
ViewDistance=1000
FOV=90
[Audio]
MasterVolume=80
MusicVolume=70
EffectsVolume=90
VoiceVolume=100
SpeakerMode=Stereo
EnableEAX=false
[Controls]
; Key bindings
MoveForward=W
MoveBackward=S
MoveLeft=A
MoveRight=D
Jump=Space
Crouch=Ctrl
Sprint=Shift
Interact=E
Inventory=Tab
Map=M
[Gameplay]
Difficulty=Normal
AutoSave=true
AutoSaveInterval=300 ; seconds
ShowHints=true
ShowSubtitles=true
Language=English
Advanced INI Patterns
Multi-line Values and Special Characters
Handling complex values in INI files
[Application]
; Some parsers support multi-line with backslash
Description=This is a very long description that continues on the next line for better readability
; Quotes are usually not required but can be used
Path="C:Program FilesMy Appin"
AltPath=C:UsersPublicDocuments
; Special characters in values
ConnectionString=Server=localhost;Database=mydb;User Id=sa;
RegexPattern=^[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z]{2,}$
; URL values
ApiEndpoint=https://api.example.com/v2
Webhook=https://hooks.example.com/webhook?token=abc123&type=config
; Escaped characters (parser-dependent)
Message=Line 1
Line 2 Tabbed
SpecialChars=Value with "quotes" and \backslashes\
PHP Configuration (php.ini)
Real-world example of PHP configuration
; PHP Configuration File
[PHP]
; Enable PHP short tags
short_open_tag = On
; Maximum execution time in seconds
max_execution_time = 30
; Maximum input time in seconds
max_input_time = 60
; Memory limit
memory_limit = 128M
; Error reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/error.log
; File uploads
file_uploads = On
upload_max_filesize = 20M
max_file_uploads = 20
; Data handling
post_max_size = 25M
default_charset = "UTF-8"
[Date]
; Timezone setting
date.timezone = "America/New_York"
[Session]
session.save_handler = files
session.save_path = "/var/lib/php/sessions"
session.use_cookies = 1
session.cookie_httponly = 1
session.cookie_secure = 1
session.gc_maxlifetime = 1440
[opcache]
opcache.enable = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 2
Git Configuration (.gitconfig)
Git uses INI format for configuration
[user]
name = John Doe
email = john.doe@example.com
signingkey = 1234567890ABCDEF
[core]
editor = vim
whitespace = fix,-indent-with-non-tab,trailing-space,cr-at-eol
excludesfile = ~/.gitignore_global
autocrlf = input
ignorecase = false
[color]
ui = auto
branch = auto
diff = auto
status = auto
[alias]
st = status
co = checkout
br = branch
ci = commit
unstage = reset HEAD --
last = log -1 HEAD
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
[push]
default = simple
followTags = true
[pull]
rebase = true
[merge]
tool = vimdiff
conflictstyle = diff3
[diff]
tool = vimdiff
algorithm = patience
Desktop Entry Files (Linux)
Linux Desktop Entry (.desktop)
Application launcher configuration
[Desktop Entry]
Version=1.0
Type=Application
Name=Visual Studio Code
GenericName=Text Editor
Comment=Code Editing. Redefined.
Exec=/usr/share/code/code --unity-launch %F
Icon=visual-studio-code
Terminal=false
StartupNotify=true
StartupWMClass=Code
Categories=Development;IDE;TextEditor;
MimeType=text/plain;application/x-code-workspace;
Actions=new-empty-window;
Keywords=vscode;editor;ide;development;
[Desktop Action new-empty-window]
Name=New Empty Window
Exec=/usr/share/code/code --new-window %F
Icon=visual-studio-code
Windows Application Settings
Windows App Configuration
Typical Windows desktop application INI
; MyApp Configuration File
; Last updated: 2024-01-20
[Setup]
AppVersion=2.5.0.1234
InstallPath=C:Program FilesMyApp
DataPath=%APPDATA%MyApp
Language=1033 ; English (US)
[MainWindow]
Left=100
Top=100
Width=1024
Height=768
State=0 ; 0=Normal, 1=Minimized, 2=Maximized
AlwaysOnTop=0
Transparency=255 ; 0-255
[Preferences]
AutoUpdate=1
CheckUpdateInterval=7 ; days
ShowSplashScreen=1
SplashDuration=3000 ; milliseconds
RememberLastSession=1
ConfirmExit=1
MinimizeToTray=1
[RecentFiles]
File1=C:DocumentsProject1.dat
File2=C:DocumentsProject2.dat
File3=D:WorkAnalysis.dat
MaxRecentFiles=10
[Toolbar]
Visible=1
Position=Top
ButtonSize=Large
ShowLabels=1
CustomButtons=New,Open,Save,null,Cut,Copy,Paste,null,Help
[Plugins]
Plugin1=AdvancedTools.dll
Plugin2=DataAnalysis.dll
Plugin3=Reporting.dll
AutoLoadPlugins=1
Network Service Configuration
Service Configuration with Multiple Instances
Server configuration with environment-specific sections
; Service Configuration
[Global]
ServiceName=DataProcessor
LogLevel=INFO
MaxWorkers=10
Timeout=300
[Server:Production]
Host=prod.example.com
Port=8080
SSL=true
CertFile=/etc/ssl/certs/prod.crt
KeyFile=/etc/ssl/private/prod.key
MaxConnections=1000
[Server:Staging]
Host=staging.example.com
Port=8080
SSL=true
CertFile=/etc/ssl/certs/staging.crt
KeyFile=/etc/ssl/private/staging.key
MaxConnections=100
[Server:Development]
Host=localhost
Port=8080
SSL=false
MaxConnections=10
DebugMode=true
[Database:Production]
Driver=postgresql
Host=db-prod.example.com
Port=5432
Name=app_production
User=app_user
PoolSize=50
[Database:Development]
Driver=sqlite
Path=./dev.db
PoolSize=5
[Cache]
Enabled=true
Driver=redis
Host=cache.example.com
Port=6379
TTL=3600
MaxEntries=10000
Best Practices and Limitations
INI Format Best Practices
- Use clear, descriptive section names
- Keep keys consistent (use camelCase or snake_case, not both)
- Add comments to explain non-obvious settings
- Group related settings in sections
- Use meaningful default values
- Document units for numeric values (seconds, bytes, etc.)
- Never store passwords or sensitive data in INI files
INI Format Limitations
- No standard specification: Different parsers behave differently
- No nested sections: Can't represent complex hierarchies
- Limited data types: Everything is a string by default
- No arrays: Must use workarounds like numbered keys
- Encoding issues: Not all parsers handle Unicode well
- Size limitations: Some Windows APIs limit INI files to 64KB
Working with INI in Different Languages
Python - ConfigParser
Reading and writing INI files in Python
import configparser
import os
# Create a config object
config = configparser.ConfigParser()
# Read INI file
config.read('app.ini')
# Access values
app_name = config['General']['AppName']
width = config.getint('Window', 'Width')
is_fullscreen = config.getboolean('Window', 'Fullscreen')
# Get with fallback
theme = config.get('General', 'Theme', fallback='light')
# Check if section/option exists
if config.has_section('Database'):
db_host = config['Database']['Host']
# Modify values
config['Window']['Width'] = '1920'
config['Window']['Height'] = '1080'
# Add new section
config.add_section('NewFeature')
config['NewFeature']['Enabled'] = 'true'
config['NewFeature']['Level'] = '5'
# Write to file
with open('app_modified.ini', 'w') as configfile:
config.write(configfile)
# Interpolation example
config_interp = configparser.ConfigParser(
defaults={'home': os.path.expanduser('~')}
)
config_interp.read_string("""
[Paths]
user_dir = %(home)s/Documents
app_dir = %(home)s/MyApp
log_file = %(app_dir)s/app.log
""")
print(config_interp['Paths']['log_file'])
# Output: /home/user/MyApp/app.log
C# - Reading INI Files
Windows API and custom INI handling in C#
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
public class IniFile
{
private string filePath;
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(
string section,
string key,
string def,
StringBuilder retVal,
int size,
string filePath);
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(
string section,
string key,
string val,
string filePath);
public IniFile(string filePath)
{
this.filePath = filePath;
}
public string Read(string section, string key, string defaultValue = "")
{
var retVal = new StringBuilder(255);
GetPrivateProfileString(section, key, defaultValue, retVal, 255, filePath);
return retVal.ToString();
}
public void Write(string section, string key, string value)
{
WritePrivateProfileString(section, key, value, filePath);
}
// Helper methods
public int ReadInt(string section, string key, int defaultValue = 0)
{
string value = Read(section, key, defaultValue.ToString());
return int.TryParse(value, out int result) ? result : defaultValue;
}
public bool ReadBool(string section, string key, bool defaultValue = false)
{
string value = Read(section, key, defaultValue.ToString());
return value.ToLower() == "true" || value == "1" || value.ToLower() == "yes";
}
}
// Usage
var ini = new IniFile(@"C:MyAppconfig.ini");
// Read values
string appName = ini.Read("General", "AppName", "DefaultApp");
int windowWidth = ini.ReadInt("Window", "Width", 800);
bool isFullscreen = ini.ReadBool("Window", "Fullscreen", false);
// Write values
ini.Write("General", "LastRun", DateTime.Now.ToString());
ini.Write("Window", "Width", "1920");
JavaScript/Node.js - Working with INI
Parsing and generating INI files in Node.js
const fs = require('fs');
const ini = require('ini');
// Read and parse INI file
const config = ini.parse(fs.readFileSync('./config.ini', 'utf-8'));
// Access values
console.log(config.General.AppName);
console.log(config.Window.Width);
// Modify configuration
config.Window.Width = 1920;
config.Window.Height = 1080;
// Add new section
config.NewSection = {
enabled: true,
timeout: 30,
retries: 3
};
// Convert back to INI format
const iniContent = ini.stringify(config, {
section: 'General', // Default section for top-level keys
whitespace: true // Add spacing around =
});
// Write to file
fs.writeFileSync('./config_modified.ini', iniContent);
// Custom INI parser for special cases
class SimpleIniParser {
static parse(content) {
const lines = content.split(/
?
/);
const result = {};
let currentSection = null;
for (const line of lines) {
// Skip empty lines and comments
if (!line.trim() || line.trim().startsWith(';') || line.trim().startsWith('#')) {
continue;
}
// Section header
const sectionMatch = line.match(/^[([^]]+)]/);
if (sectionMatch) {
currentSection = sectionMatch[1];
result[currentSection] = result[currentSection] || {};
continue;
}
// Key-value pair
const keyValueMatch = line.match(/^([^=]+)=(.*)/);
if (keyValueMatch && currentSection) {
const key = keyValueMatch[1].trim();
const value = keyValueMatch[2].trim();
result[currentSection][key] = value;
}
}
return result;
}
}
// Usage of custom parser
const customConfig = SimpleIniParser.parse(fs.readFileSync('./app.ini', 'utf-8'));
Migration Strategies
When to Migrate from INI
Stay with INI when:
- Simple key-value configuration
- Windows desktop applications
- Legacy system compatibility
- User-editable settings needed
- Minimal dependencies preferred
Consider migration when:
- Need nested data structures
- Require data validation
- Want type safety
- Need array/list support
- Cross-platform compatibility crucial