Skip to content
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


SoulverCore is a Swift framework that lets you easily evaluate mathematical expressions. It powers the popular Mac notepad-calculator app Soulver. It has a very simple API with sensible defaults, and is also quite customizable ("simple things are easy, complex things are possible").


  • Xcode 11+
  • Swift 5+

Supported Platforms

SoulverCore is distributed as a binary framework (.xcframework) and supports macOS, iOS, & iPadOS.

  • macOS 10.14.4+
  • iOS/iPadOS 12.2+


Drag SoulverCore.xcframework into the Frameworks, Libraries, and Embedded Content section of the General settings for your Mac or iOS target.

Getting Started

To calculate the result of a single expression, use a Calculator:

import SoulverCore

let calculator = Calculator(customization: .standard)
let result = calculator.evaluate("123 + 456")
print("The answer is \(result.stringValue)") // prints 579

SoulverCore has a lot of features for day-to-day math, including unit calculations, calendar calculations, rate calculations, percentage phrase functions, and time zone conversions. It also cleverly ignores "meaningless" words:

calculator.evaluate("$10 for lunch + 15% tip") // $11.50
calculator.evaluate("65 kg in pounds") // 154.32 lb
calculator.evaluate("40 as % of 90") // 25%
calculator.evaluate("$150 is 25% on what") // $120
calculator.evaluate("$25/hour * 14 hours of work") // $350.00
calculator.evaluate("January 30 2020 + 3 months 2 weeks 5 days") // 19 May
calculator.evaluate("9:35am in New York to Japan") // 10:35 pm
calculator.evaluate("$25k over 10 years at 7.5%") // $51,525.79 (compound interest)


Use a VariableList to customize variables in your expression:

let variableList = VariableList(variables:
        Variable(name: "a", value: "123"),
        Variable(name: "b", value: "456"),
calculator.evaluate("a + b", with: variableList) // 579        

Output Formatting

Use a FormattingPreferences to customize the formatting of your result.

var formattingPreferences = FormattingPreferences()
formattingPreferences.dp = 2 // decimal places
calculator.formattingPreferences = formattingPreferences

calculator.calculate("π") // 3.14

Custom Units

You can add custom units to an EngineCustomization.

var customization: EngineCustomization = .standard

customization.customUnits = [
    CustomUnit(name: "parrots", definition: 15, equivalentUnit: .centimeters),
    CustomUnit(name: "python", definition: 570, equivalentUnit: .centimeters)

let calculator = Calculator(customization: customization)
calculator.calculate("1 python in parrots") // 38 parrots

Locale settings

SoulverCore respects the decimal separator and thousands separator of the current locale. Alternatively, convert the standard EngineCustomization to another locale:

let europeanLocale = Locale(identifier: "en_DE") // In Germany a comma is used as the decimal separator
let localizedCustomization = EngineCustomization.standard.convertTo(locale: europeanLocale)

let calculator = Calculator(customization: localizedCustomization)
calculator.calculate("1,2 + 3,4") // 4,6

Multi-line calculations

Use a LineCollection to represent a list of lines to be evaluated. The LineCollection creates its own calculator, though you can still pass in your own customization.

let multiLineText =
a = 10
b = 20
c = a + b
let lineCollection = LineCollection(multiLineText:
    multiLineText, customization: .standard)

// Calculate the result of each line (synchronously)

// Use subscripts to get access to particular lines' results
let result = lineCollection[2].result // 30

Line References

A line collection manages dependencies between lines. You can also get a "reference" to a line. A reference is a single unicode character, which is a placeholder for the line's answer (which will be substituted in during evaluation).

let multiLineText =

let lineCollection = LineCollection(multiLineText:
    multiLineText, customization: .standard)

let referenceToFirstLine = lineCollection.makeReferenceForLineAt(lineIndex: 0)
let referenceToSecondLine = lineCollection.makeReferenceForLineAt(lineIndex: 1)

lineCollection.addLine("\(referenceToFirstLine) + \(referenceToSecondLine)")

// Calculate the result of each line

print(lineCollection[2].result!.stringValue) // 30

Currency Rates

The standard customization comes with rates for 170 real-world currencies, that were accurate at the time the framework was last compiled. You can update these currencies to the latest rates by setting valid API key credentials for CurrencyLayer and Nomics on the shared CurrencyList. Alternatively use the .popular default currency set to pull 33 currency rates from the European Central Bank, no API key required.

To fetch the latest rates, use SoulverCore's shared CurrencyList:

CurrencyList.shared.defaultCurrencySet = .popular // 33 popular currencies from the ECB, updated every weekday.

CurrencyList.shared.refreshRates { (success) in
	if success {  
		// The standard customization will now have the latest currency rates applied		
		let calculator = Calculator(customization: .standard)
		let result = calculator.calculate("10 USD in EUR")  		

Additional languages

SoulverCore is localized into German, Russian, simplified Chinese & traditional Chinese.

Carthage Support

SoulverCore supports Carthage. Add the following binary dependency to your Cartfile:

binary ""

More information

SoulverCore has all the calculation features of Soulver. Check out Soulver's documentation for more information on supported syntaxes.

Examples of SoulverCore in Use

  • Lacona - a powerful natural language assistant/launcher for macOS
  • Toolbox Pro - calculate with Soulver as part of your Siri Shortcuts on iOS


You may use SoulverCore in personal/private projects. Please email us if you wish to use SoulverCore in a publically available or commerical project.

You can’t perform that action at this time.