My Adobe ColdFusion 2025 Hackathon Entry
This is the write-up for my Adobe ColdFusion (ACF) 2025 Hackathon submission. The primary goal of the hackathon is to have fun. The secondary goal of the hackathon is to showcase at least one of the features newly available in the latest version of ACF.
View this code in my Hackathon project on GitHub.
Entry Restrictions
The hackathon took place from June 14-16, 2025 and had the following requirements:
- Application must run on Adobe ColdFusion 2025.
- Submissions must be self-contained and runnable (drop into
cfusion/wwwroot
). - Any included libraries must be open source licensed.
Hackathon: "Sitter Snacks"
We have a dog, Lucy. She's a geriatric Yorkie with extreme separation anxiety and a problematic bladder. As such, she has a lot of trouble being left on her own. So, when we go out, we hire a dog sitter to come and keep Lucy company while we're at the restaurant / movie / hike, etc.
Leading up to these outings, I go and get snacks for the sitter; and, if the outing overlaps with a meal, I'll ask her if she wants something more substantial like a pizza or a burger or something. As a hackathon idea, I thought it would be fun to create a small website where she can go and explicitly select the snacks that she wants (instead of me guessing); and then I can pick them up at the store on the day-of.
I'm calling this website "Sitter Snacks". It has one primary page experience, broken down into sections:
- Emergency contact information.
- Drinks.
- Snacks.
- Meals.
- QR Code.
Next to each entry within the drinks, snacks, and meals section is a toggle button that indicate the desire for that specific amenity. It's essentially a menu (in the restaurant sense) that the sitter is opting into:
Each of the sections has a separate configuration page that allows the line-items to be added, edited, and removed.
Built Using Docker For Mac
I build this using Docker For Mac. If you want to run this, you should be able to just pull-down the repository and run:
docker compose up
... from within the root directory.
ColdFusion 2025 Feature Exploration
Here are the ColdFusion 2025 features that I was trying to explore in this hackathon:
Aside: keep in mind that my hackathon contains basically no error handling and is extremely light on any architecture. But, in a way, that's a feature of ColdFusion as well — that it can be as robust or as light-weight as you need it to be. The effort of the build is commensurate with the complexity of the application.
.csv
)
CSV Files (Example: CsvFileProxy.cfc
One of the biggest new features in ACF 2025 is the ability to read, write, and process CSV (Comma Separated Value) data. To explore this, I'm storing each user's contact info, drinks, snacks, and meal data in a set of CSV files contained within an UUID-based user-specific folder.
.properties
)
Property Files (Example: PropertiesFileProxy.cfc
ACF 2025 gives us the ability to create and consume .properties
files. A .properties
files is a relatively simple collection of key-value pairs. I'm using this in two ways:
- Store configuration settings for the application itself.
- Store some metadata about the user who signed-up.

JAR Paths
Example: BarCoder.cfc
Another very exciting (perhaps the most exciting) feature of ACF 2025 is the ability to provide a list of JAR paths to the createObject()
call. Now, we can load custom Java libraries with better class-loader isolation. In this project, I'm using this to load the ZXing barcode library that I then use to render the shareable QR code at the bottom of the site.
Content Security Policy (CSP)
Example: layout.cfm
Since this site is rendering user-generated content (UGC), security is a consideration. I've included the this.enableCspNonceForScript
setting in my Application.cfc
, which automatically injects a Content-Security-Policy
HTTP header with a randomized nonce (n-once). Then, I'm using the new getCspNonce()
function to apply this nonce to my script and link tags.
Null Coalescing
Example: flattenForm()
In addition to "partially fixing" the Elvis Operator (no longer treating the empty-string as a falsy), ACF 2025 introduced the null coalescing operator (??
). This works similarly to the Elvis Operator, but the right-hand expression is only used if the left-hand value is null
/ undefined
(ie, the notions of truthy/falsy don't apply). I'm using this in a bunch of places when consuming data that may not be fully defined.
Trailing Commas
Example: this.mappings
ACF 2025 now allows trailing commas in a variety of places such as array and struct definitions. This really has no inherent application value other than developer experience (DX). Specifically, it allows git diff
rendering and Pull Request (PR) rendering to be a little cleaner. This is really only relevant when working with other developers who are reviewing PRs. That said, I'm using it in a bunch of places in the hackathon.
Road Bumps and Bugs
In addition to running out of time, and not getting to all the little features I wanted to explore, I also ran into some issues along the way.
No Docker build for Apple M1/ARM silicon. I'm a MacBookPro 2022; and I was promised an M1 build in the second 2025 Beta release; but, apparently, this never made it into the roadmap. Thankfully, the good people over at Ortus Solutions provide an ARM build for all versions of ColdFusion.
this.enableCspNonceForScript
breaksCFDump
/writeDump()
. The wayCFDump
operates is that it renders both a<style>
tag and a<script>
tag in the page response. However, neither of these tags include thegetCspNonce()
functionality. So, your data is still dumped-out; but, it has no styling or interactivity.To get around this, I capture the output buffer, check for the substring,
table.cfdump_
, and if it exists, I override the CSP HTTP header to allow everything (essentially disabling the CSP).The CSP HTTP header that ColdFusion applies does not include any information about inline
<style>
tags. Which means, even if I apply agetCspNonce()
to my<style>
tag, the browser will still reject it. I'm using HTMX in this project for the toggle-buttons. And, to get around the CSP issue, I had to tell HTMX not to inject loading-indicator styles.The
arrayOfStruct
format for CSV file generation is completely broken. The columns of the CSV are output in the order of the struct-key iteration (which is entirely unpredictable) instead of in the order of theheader
columns definition. To work around this, I map the data onto the thearrayOfCFArray
format just before I callcsvWrite()
.ACF 2025 doesn't support unsigned integers. As such, when I use a value like
ffcccccc
to define the colors for the ZXing barcode, ACF complains that it can't fit it into anint
. To get around this, I use the "two's complement", where I subtract4294967296
from the value in order to translate it into anint
range.The
writeDump()
function doesn't allowvar
to be passed-in as part of theargumentCollection
mechanics. As such, in mydump()
alias UDF (user defined function), I have to explicitly provide thevar
argument in addition to theargumentCollection
.ACF 2025 still doesn't allow the
cfloop(collection)
to define both anitem
(value) and anindex
(key). You can do this with acfloop(array)
. As such, I have to calculate thevalue
within the iteration body of a struct.ACF 2025 still doesn't allow
field[]
notation for collecting form field submissions as an array. As such, I have to polyfill this functionality in theonRequestStart()
application life-cycle event handler.array.each()
doesn't return the array reference, it returnsundefined
. As such, you can't include.each()
in a fluent set of operations on an array. As such, it just has to be part of a subsequent statement.array.isDefined(0)
throws an out-of-bounds error. It should just returnfalse
since0
is not defined on the array. As such, I sometimes have to check.len()
instead of using.isDefined()
.
And yet, I had a blast! 'Cause CFML is the cat's pajamas, yo!
This ColdFusion code was 99.99% human generated (someone has to train the slop machines). I needed help from ChatGPT to figure out the two's complement issue for the int
error. And, I used it to try and figure out the getCspNonce()
bug for <style>
tags.
Fun fact: the movie Happy Gilmore came out 13 years before my dog sitter as born. I'm officially old :scream:
Reader Comments
I'm trapped in a windoze machine world, but I want to try to get it going in docker...
And I hope those are bogus phone numbers (though I messaged yours) cause you don't want every curious yahoo (like me) reaching out to you... (or maybe you do!)
Anyway looking forward to wading through your code and learning a few things and many thanks for pointing out the pitfalls in this release of 2025 as well as a bit of what can be done wid it!
@All,
I'm excited to announce that I came in 2nd place in the ACF 2025 Hackathon - Mark Takata announced it on LinkedIn. Woot woot! Can't wait to see the other contestant code - will share a link here when I know what it is.
@Jeff,
All good - any
555
number in the US is "fake". It's what they use in the movies.Stuck with new machine setup, what would you use as an IDE to work with CF in 2025? Many thnaks in advance
@Will,
Personally, I still use SublimeText as my IDE. And there's a CFML package for it (maintained by a few people), I think. But, I'm pretty sure that Adobe now has a Visual Studio Code extension. But, I don't know much about it.
@Ben Nadel, Thanks Ben, appreciate it 👍
Post A Comment — ❤️ I'd Love To Hear From You! ❤️
Post a Comment →