This will probably be a rant but I recognize that things will improve over time.
I just launched 20 new simple Forge apps on the marketplace as a test of the platform. The platform is really not production ready for complex apps and has incredibly frustrating DX and end-user UX.
Went pure UI Kit because I knew Custom UI would be easier and more flexible to build in Connect. Also I wanted to jump in early on the MacroConfig sidebar which is currently exclusive to UI Kit.
- Documentation and tutorials work. When I first started building Connect apps ~2-3 years ago the docs were so outdated that the hello world tutorial didn’t work.
- The community forums are more active and have answers to questions (unlike Connect).
- The CLI is cool and very easy to get started.
- The app examples are good.
- If you’re building any kind of macro with Forge, on first install it will show an “Allow Access” prompt. However this button is unclickable in the editor. Incredibly poor oversight.
- Apparently this is set to be fixed in Q4 2022 (why so late?!).
- To be honest it’s such a bad UX onboarding blocker that I wouldn’t recommend building any Forge macro app until this is fixed (2023 I guess).
- Also see MacroConfig section below…
- Prior to these simple 20 apps I tried to build a more complex voice-based app with Custom UI. The problem is the security lockdown on Forge is so intense that you’ll constantly hit a wall with the apps and packages you wish to use. eg if you want to use an npm package that happens to call
windowanywhere in that package, Forge will prevent it from running. There’s other simple JS that are blocked by Forge but you won’t find a list anywhere in the docs. Also if that package pulls a file from a CDN, you’ll need to manually include that CDN domain into your manifest file. It’s so painful it really isn’t worth using any external npm packages (which is 99.9% of dev these days).
- I’m a solo dev so collaboration wasn’t an issue, but currently there is no clean way for multiple developers to work on the same app. Therein lies many of the downsides of Atlassian forcing developers to do use their server-side infrastructure for all developer environments. I currently manage 362 marketplace apps on Cloudflare’s infrastructure and it literally costs me $0 to host and $5/mth to serve millions of API calls per week. Once Atlassian lock developers into using Forge for all CI/CD and begin charging to use that service; I have no doubt it will be more expensive, slower and more cumbersome than what most devs currently use.
forge tunnelrandomly crashes every 5-10min which requires a restart. It’ll also timeout with no warning other than a non-descript error message in the Confluence/Jira UI. I’d suggest the team switch out ngrok for Cloudflare Tunnel. All of my Connect apps have code splitting which is frustrating when using the inbuilt ngrok because there’s a low total request limit per 60 seconds.
- Debugging is a nightmare since everything is running server-side on Atlassian’s infrastructure. So your
console.log()will only display inside the terminal and the CLI will rarely throw useful error messages.
- The storage limits are from the 1990s. I’d challenge anyone at Atlassian to attempt to build a polls or forms app on either Connect or Forge where all the data remains within the customer’s instance. Low storage limits encourage developers to store data externally which becomes a security issue. 32KB limit for a key-value is painfully restricting. That’s now been increased to 128KB on Forge (still 32KB on Connect). But for comparison, Cloudflare Workers KV have a 25MB limit. My workaround on both platforms is an elaborate set of functions to split data into 32KB or 128KB chunks and then loop to post/put/get data across multiple KVs (key:0, key:1, key:2 etc).
- UI Kit is severely limiting. At least with AtlasKit you’re using it with React and have access to full HTML. In UI Kit you cannot use HTML anywhere. I’m assuming the goal is to reach parity with the features of AtlasKit. But it’s also bizarre that the Atlassian developer ecosystem now has three siloed component kits which are all incompatible: AUI, AtlasKit, UI Kit.
- Here’s one of many limiting hurdles: you cannot apply a href link to a button or image. Instead there’s a separate
<Link/>component. Oh and that component has far less appearance options than
<Button/>. Why wasn’t a href prop simply added?!
- Another annoying one is the lack of standardization in regards to component props. eg
<Button/>colors are danger, default, link, subtle, subtle-link, warning.
<Badge/>colors are added, default, important, primary, removed.
<Tag/>colors are green, blue, red, purple etc.
- Also root level modules have non-standard component props. eg ContextMenu wants children, Macro does not:
- Basic conditional code doesn’t work. Throughout my codebase I’ve had to write things like this because the normal way you’d write it doesn’t work:
- Also found I had to declare default fallback values directly inside the props because if you set them higher up while deconstructing, it doesn’t work:
- Oh boy. This was the primary exclusive UI Kit feature I wanted to use and it was a nightmare. For simple static apps where the config options never change, it’s passable. If you want to dynamically show/hide various form fields within
<MacroConfig/>then you’re gonna have a bad time.
- You’re not allowed to use
<MacroConfig/>so that rules out doing anything with complex config UI. So instead what I did was overkill it and use AI to map natural language into compatible UI Kit components. ie user types in “red button” and I render the config fields dynamically with
<TextField name="color" defaultValue="red"/>. Subsequently this limitation became the general theme of all the Forge apps I built.
- Problem is once you dynamically render
MacroConfigform fields, there is no way to programmatically call the
useConfig()hook. So your rendered macro will not get updated props until a user manually changes data in the dynamically rendered config form fields.
- So in order to then get the user to see a red button I have had to save the MacroConfig user input to a
contentPropertyand then compare that data to the currently accessible
useConfigdata in the rendered macro. If there’s a mismatch I display a GIF to the user in an attempt to educate them on how to use the stupid autosave UX of the macro config sidebar.
- The “autosave” sounds great in theory. But it’s not autosave onKeyUp. No, the user needs to either press enter or click outside of an input field. If you click outside of the sidebar it hides the sidebar. It’s incredibly unintuitive. Even the folks reviewing my marketplace app submissions don’t understand how to use it (I literally just sent a Loom to explain it). Autosave without actually saving on each keystroke is a truly bad UX decision. And there needs the ability to programmatically call
useConfig()to avoid unsynced data between the config sidebar and the rendered macro.
- I like to bulk build apps in a mono-repo to maximize the use of my time since the static Marketplace homepage (same featured apps every bloody day!) and Cloud Fortified program (an outrageous $5k per app to join!) discriminate against all but the largest entrenched app vendors. So you really need to play the longtail if you want to eat. To achieve this I had to create 20 separate manifest files and a batch file to loop deploy the apps.
forge lintwill lint the entire codebase and not just the specific app you’re deploying/testing. Which meant if one app only required a subset of permissions, I still had to include the same permissions across all 20 manifests in order for Forge to allow the deployment.
- Manifest permission naming rules randomly changed halfway through development. The permission docs are out of date and don’t reflect what the latest version of
forge lintwill throw at you.
- Your personal name used to signup to access the Developer Console will be shown to end users in the macro insert dropdown and in the MacroConfig sidebar. It’s being fixed, but my apps now live on the marketplace show my full name to the user instead of my vendor name. Here’s the ticket to follow: [FRGE-636] - Ecosystem Jira. Somehow I was the first person to bring this to Atlassian’s attention.
That’s as much as I can remember. Hopefully it helps folks on the Forge team make some improvements.
Really hoping the team workout a way for me to run my static Connect apps inside a Forge-like sandbox, because I have no interest in migrating them across given the level of pain that will involve.