Skip to content

Instantly share code, notes, and snippets.

@HoussemNasri
Last active July 10, 2025 22:09
Show Gist options
  • Save HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28 to your computer and use it in GitHub Desktop.
Save HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28 to your computer and use it in GitHub Desktop.
Extend your trial period for Balsamiq Wireframes on Windows and macOS Forever!

Overview

This script will prolong your trial time for Balsamiq Wireframes on both Windows and macOS. You may also manually apply the hack by following the steps in Manual Editing.

Prerequisites

  • python3

⚠️ Warning: Close all balsamiq wireframes instances before proceeding, otherwise the operation won't succeed.

Run the script

⚠️ Works only on Windows, for MacOS check the Manual Editing section.

  1. Download and install python3
  2. Download the script and extract it
  3. Open the terminal and navigate to the script location
  4. Close Balsamiq
  5. Run python BalsamiqForever.py or python3 BalsamiqForever.py

Manual Editing

If running the script didn't do it or you just want to get your hands dirty, here is how to apply the hack manualy by editing configuration files on the application folder.

Windows

  1. Open this file in your text editor %APPDATA%\Balsamiq\Balsamiq Wireframes\LocalSettings.json.
  2. Edit DefaultSelectionColorRGBA property and increase it's value.

For example, if you're using this configuration "DefaultSelectionColorRGBA": 1916130510, your trial will expire in September 20, 2030 🤯, for custom expiration date use this website.

  1. Save changes.

MacOS

Adding support for macOS wouldn't be possible without the help of @pep108 and @megatunger.

  1. Open this file in your text editor /Applications/Balsamiq Wireframes.app/Contents/Resources/editor-macos.js.
  2. Search for this function function getLicenseValidFromLicenseData(data).
  3. Replce function body by return true.
//result
function getLicenseValidFromLicenseData(data) {
      return true
}
  1. Save.
import json
import os
import time
import webbrowser
import sys
import re
def handleWindows(extra_seconds):
print("OS : Windows")
local_settings = r"{}\Balsamiq\Balsamiq Wireframes\LocalSettings.json".format(os.getenv('APPDATA'))
print("Reading from {}".format(local_settings))
with open(local_settings) as reader:
json_data = json.load(reader)
json_data['DefaultSelectionColorRGBA'] = int(time.time()) + extra_seconds
print("Writing to {}".format(local_settings))
with open(local_settings, 'w') as outfile:
json.dump(json_data, outfile)
def handleMacos(trial_days_left=30, debug_mode=False):
print("OS : macOS")
print("Debug Mode: " + str(debug_mode))
def dump_debug(start_func, end_func, content_func, new_func):
print("function start line: {}".format(start_func))
print("function end line: {}".format(end_func))
print("function content:")
print(content_func)
print("new function content:")
print(new_func)
editor_macos = "/Applications/Balsamiq Wireframes.app/Contents/Resources/editor-macos.js"
editor_macos_test = r"C:\Users\housi\Desktop\Balsamiq\editor-macos-test.js"
if debug_mode:
editor_macos = editor_macos_test
print(editor_macos)
if not os.path.exists(editor_macos):
print("editor-macos.js NOT FOUND!")
exit(0)
get_trial_days_left_pattern = re.compile(r"\s*function\s+getTrialDaysLeftFromNativeData\(\w+\)\s*{")
func_start_line = -1
func_end_line = -1
found_a_match = False
function_content = ""
with open(editor_macos, encoding="utf8") as reader:
line_number = 0
# it starts at 1 because w have already matched one '{'
curly_braces_balance = 1
for line in reader.readlines():
line_number += 1
if not found_a_match:
match = get_trial_days_left_pattern.match(line)
if match is not None:
found_a_match = True
func_start_line = line_number
# TODO what if the start line is also the end line, One-Liner function
else:
curly_braces_balance += line.count("{")
curly_braces_balance -= line.count("}")
if curly_braces_balance == 0:
function_content = function_content + line
func_end_line = line_number
break
if func_start_line != -1:
function_content = function_content + line
body = "return {};".format(trial_days_left)
new_function_signature = "\nfunction getTrialDaysLeftFromNativeData(nativeData) {\n\t" + body + "\n}\n\n"
if debug_mode:
dump_debug(func_start_line, func_end_line, function_content, new_function_signature)
with open(editor_macos, encoding="utf8") as reader:
lines = reader.readlines()
# The first -1 to make it base 0 and the second one refers to the previous index
index = (func_start_line - 1) - 1
leading_count = 0
# Removing leading blank lines before the function definition
while not lines[index].strip():
lines.pop(index)
index -= 1
leading_count += 1
# The start and end indexes will change after removing the leading blank lines
func_start_line -= leading_count
func_end_line -= leading_count
# Removing trailing blank lines after the function end
index = func_end_line
while not lines[index].strip():
lines.pop(index)
# Removing the old function
for i in range(func_end_line - func_start_line + 1):
lines.pop(func_start_line - 1)
# Replacing it with the new function
lines.insert(func_start_line - 1, new_function_signature)
# Writing changes back to file
with open(editor_macos, "w", encoding="utf8") as f:
lines = "".join(lines)
f.write(lines)
print("IMPORTANT! please make sure to close Balsamiq before proceeding or the script won't have any effect")
years = int(input("How many years of trial do you want :) "))
if sys.platform.startswith("win"):
handleWindows(years * 365 * 24 * 60 * 60)
elif sys.platform.startswith("darwin"):
handleMacos(years * 365)
else:
print("Sorry, operating system not supported")
exit(0)
print("****************************************************************")
print("* Congratulations! You gained {} days of trial".format(years * 365))
print("* Please don't forget to leave a star ✭")
print("****************************************************************")
print("https://gist.github.com/HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28")
webbrowser.open("https://gist.github.com/HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28")
input("Press ENTER to exit")
@mamedee
Copy link

mamedee commented Feb 17, 2022

It works!
image

@Jmack69
Copy link

Jmack69 commented Feb 27, 2022

Hi friend, you are the master....
image

@yufanme
Copy link

yufanme commented Mar 5, 2022

works for me.
image
maybe 100000000000000000000000000000 years is enough
image
you deserve 5 star, man.
great job!

@HoussemNasri
Copy link
Author

HoussemNasri commented Mar 5, 2022

@yufanme The script doesn't work for macOS, have a look at the manual editing section https://gist.github.com/HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28#run-the-script

@yufanme
Copy link

yufanme commented Mar 5, 2022

@yufanme The script doesn't work for macOS, have a look at the manual editing section https://gist.github.com/HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28#run-the-script
thx HoussemNasri, I did that manually, and how can I check if that works

@yufanme
Copy link

yufanme commented Mar 5, 2022

@yufanme The script doesn't work for macOS, have a look at the manual editing section https://gist.github.com/HoussemNasri/c09e55e0e5f451aa10f8621a6680ba28#run-the-script

the information box seems not change, so I should restart my mac to make that work?

@HoussemNasri
Copy link
Author

the information box seems not change, so I should restart my mac to make that work?

No need to restart, it works unlimited regardless of how many trial days you got.

@gazzabwoy
Copy link

This works a treat... thanks very much!!

@bhaktisf
Copy link

This works like charm!
Thanks a lot!

@ZetaBayt
Copy link

thanks @HoussemNasri it's still works
if "DefaultSelectionColorRGBA" like this 1648016208.7415917, you should "DefaultSelectionColorRGBA": 1916130510.

@newmanstuff
Copy link

Getting error on macOS, please help!

@polat-code
Copy link

manual editing works for windows . Perfect. Thanks.

@Quiroa
Copy link

Quiroa commented Mar 25, 2022

Gracias mano por el código, me funciono con Balsamiq 4.4.8.26.
Nota: lo probé el 24-03-2022 en una computadora con W11

@jsalafica
Copy link

Funciona perfecto con la version 4.4.8 - Editor version 3.10.4
Lo hice manual editando el archivo de configuración LocalSettings.json
Saludos!

@Artaherzadeh
Copy link

Can you find a way to extend Axure RP 10 trial?

@NullExir
Copy link

NullExir commented May 2, 2022

Thank you Very Much

@judexes
Copy link

judexes commented May 21, 2022

Thanks a bunch

@rubenqba
Copy link

I can't make it work on mac. In my case the trial period is already expired. I run the python script and manually edit the editor-macos.js file and nothing happens.

@nediazc
Copy link

nediazc commented Jun 22, 2022

Not working for the last version 4.5.3 in mac

the message here does not disappear:

image

and about Balsamiq still in 30 days

image

@HoussemNasri
Copy link
Author

@nediazc Thanks for reporting this! They must have modified the trial handling mechanism. I'll have a look at the updated version and make the necessary changes to the readme and script.

@nabiladnan18
Copy link

Amazing!

@stiggy87
Copy link

stiggy87 commented Jul 1, 2022

@nediazc Thanks for reporting this! They must have modified the trial handling mechanism. I'll have a look at the updated version and make the necessary changes to the readme and script.

Looks like the value should keep the decimal.

"DefaultSelectionColorRGBA":1916130510.3766797

When I did that, it worked.

@AngeloContreras
Copy link

Working 07/07/22 ❤🤑👌

@kiyara0104
Copy link

Can someone share the crack key for v4.5.4?

@axelcasauran
Copy link

works like a charm in v4.5.5

@eighteentee
Copy link

eighteentee commented Oct 11, 2022

Not working on MacOS - BW 4.6.1. Editing the JS to change the function to return True causes the app to constantly crash on launch. There must be something burried

@ibnux
Copy link

ibnux commented Oct 12, 2022

@eighteentee
Copy link

@eighteentee this is how i fix it

https://appletoolbox.com/app-is-damaged-cannot-be-opened-mac/

sometimes need to reSign https://gist.github.com/rampfox/7bb8d267bca6cb2b47cafdd944c5777a

I don't think it's a code-signing issue; the app doesn't throw up the standard 'This App is Damaged" MacOS dialog box. Rather, it starts to open the BW main loading window and gets stuck in a loop of opening-and-closing until you initiate Activity Monitor to terminate the app by force. I don't think the JS file is the only part of the licensing mechanism...

@ibnux
Copy link

ibnux commented Oct 12, 2022

@eighteentee it works using command on first link
Using xattr -r -d com.apple.quarantine

If it not works, the script edited wrong.

I just use it on the latest Balsamic

@eighteentee
Copy link

eighteentee commented Oct 12, 2022

Simply editing the JS file and changing the function getLicenseValidFromLicenseData(data) to return true no longer works. This is what throws the load-loop. This is on 4.6.1.

Running the script results in:
Screenshot 2022-10-12 at 10 07 52

Banner says 3650 days remaining. App dialog says 29 days remaining.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment