Last week, I was browsing through several SAP Analytics Cloud (SAC) related blog posts in the SAP Community. One post that particularly caught my attention was an excellent article by a colleague titled "Development Experience Sharing for SAC Widget Add-on." (https://community.sap.com/t5/technology-blog-posts-by-sap/development-experience-sharing-for-sac-wid...).
In his blog post, he explains how to build a custom SAC Widget Add-on and shares hands-on lessons learned from the development process, especially in the context of extending SAC charting capabilities to support a broader range of visualization requirements.
Reading this reminded me that it was time to get hands-on again. Having already gone through the manual process in the past, and after successfully experimenting with a similar scenario using SAP Joule for Consultants, I was curious to see how the same task could be approached with Claude Code.
Since I have a strong interest in AI technologies, I saw this as a great opportunity to explore how AI could support and simplify the development of an SAC widget add-on. Scenarios like this are especially interesting to me because they go beyond a single technical exercise and connect to broader conversations around SAP BTP, SAP Business Data Cloud, AI, and new development patterns. These are also exactly the kinds of topics I regularly share and discuss in my LinkedIn community: https://www.linkedin.com/groups/13112863/
Before diving into the implementation, I would like to briefly show the target outcome. The following animated GIF gives a quick preview of what this blog post will build.
With the goal defined, itβs time to get started. I began by launching Claude Code. Before doing so, I had already prepared my project folder by adding a PDF file containing the relevant SAP blog post. This document served as the initial knowledge base for the AI. As a first step, I prompted Claude Code to review this document to establish the necessary context for building the SAC widget add-on.
After providing the initial prompt, Claude Code analyzed the PDF and generated a structured summary of the blog content. What stood out to me was how quickly it captured the key concepts of SAC widget add-ons, including architecture, file structure, and core mechanisms like setExtensionData(). What impressed me most was the structured breakdown of key elements such as the different add-on types, the role of the index.json, and how rendering is handled via setExtensionData(). Instead of manually extracting and structuring this information, Claude Code provided an instant, well-organized overview that I could directly use as a foundation for the implementation.
Once the context was established, I moved on to defining a concrete use case. Instead of starting with something complex, I chose a simple but visually impactful enhancement. I asked Claude Code to create a widget add-on, not a custom widget, that renders a bar chart with rounded edges. This distinction is important, as the goal was to extend SACβs native chart capabilities rather than replacing them entirely. By explicitly requesting a widget add-on, I ensured that the solution would leverage SACβs native data binding and charting features while only modifying the visual rendering.
Rather than generating code immediately, Claude Code responded with a clarification question. It asked which chart orientation I wanted to support, offering options such as vertical, horizontal, or both. I liked this step because it showed a more interactive and structured approach to development. Instead of making assumptions, Claude Code narrowed down the requirement before moving on to implementation. For this first experiment, I selected a horizontal bar chart. This kind of guided interaction is especially helpful when working on UI extensions, where small design decisions can directly influence the implementation logic.
At this stage, Claude Code continued supporting the process by asking the next logical question around the visual design of the chart. It proposed several options for how the bars could be rounded, for example only on one side, on both sides, or later through a configurable settings panel. What I found especially helpful was the way the AI translated this design decision into a few simple choices. SAC remained the foundation throughout the process, while Claude Code acted as a supporting tool that helped structure the implementation step by step. For this example, I followed the recommended option and chose to round only the right end of each bar.
At this point, Claude Code took the next step and asked whether the add-on should include a settings panel in the SAC Story to adjust the corner radius, or whether a fixed default value would be enough. I found this especially useful because it showed that the AI was not only helping with the technical implementation itself, but also considering how the add-on should be used inside SAC later on. This is where the support from Claude Code became even more interesting. SAC remained the core platform and the actual target environment, while Claude Code helped structure the design decisions around usability and flexibility. For this first iteration, I decided to keep things simple and use a fixed radius.
Claude Code then focused on how data labels should be handled. It offered different options, such as keeping the native SAC labels, replacing them with custom-rendered labels, or removing them entirely. What I found particularly strong here was that the AI explicitly included the option to keep SACβs native labels. This reinforced that the goal was not to replace SAC functionality, but to extend it in a controlled and meaningful way. Claude Code helped make this decision transparent and easy to understand, while still aligning with how SAC works under the hood. For this scenario, I decided to keep the native SAC labels.
At this stage, Claude Code moved beyond asking questions and started proposing concrete implementation approaches. It presented three different technical options for rendering the rounded bars, ranging from SVG-based solutions to a simpler HTML and CSS-based approach. What I found particularly valuable was that the AI did not just list the options, but also explained the trade-offs. It highlighted differences in complexity, precision, and maintainability, and even provided a clear recommendation. This felt less like a code generator and more like working with a developer who walks you through the decision-making process. SAC remained the execution environment, while Claude Code helped structure the implementation choices in a transparent and easy-to-understand way. For this scenario, I followed the recommendation and selected the CSS-based approach using border-radius.
After selecting the preferred approach, Claude Code moved on to defining the actual project structure. It proposed a clean and minimal setup consisting of the required SAC add-on files, including the index.json, the main JavaScript file, and an optional settings panel. What stood out to me was how well the AI aligned with SACβs add-on architecture. The structure followed the expected pattern, including the correct extension point and a clear separation between metadata, rendering logic, and configuration. Claude Code essentially translated the conceptual understanding from earlier steps into a concrete, ready-to-implement design. It even suggested a default property like cornerRadius, making the add-on immediately configurable and ready for practical use. SAC remains the platform that defines how add-ons need to be structured and executed, while Claude Code helps accelerate the path from idea to implementation.
I decided to instruct Claude Code to go ahead and create the content.
At this stage, Claude Code moved from planning into full execution and created all required source files automatically. It generated the complete add-on structure, including the index.json, the main rendering logic, and the settings panel. Each file followed the expected SAC add-on conventions and was ready to be used without manual adjustments. What stood out to me was how the AI not only created the code, but also handled the packaging. It automatically bundled the files into a ZIP archive, exactly in the format required for uploading into SAC. This is where the value became very tangible. SAC still defines the structure, runtime, and integration of the add-on, but Claude Code significantly reduced the effort needed to get from idea to a working artifact. It even provided clear instructions on how to upload and use the add-on in SAC, making the final step straightforward and easy to follow.
After the execution was completed, all generated files were available directly in the project folder. The structure fully matched what is required for an SAC widget add-on. This included the index.json, the main implementation file, the settings panel, and the final ZIP archive prepared for upload. What I found particularly impressive was that everything was created end to end without manual intervention. From understanding the requirements to generating the code and packaging it correctly, Claude Code handled the entire flow. SAC remains the platform where the add-on is ultimately deployed and executed, but Claude Code significantly simplified and accelerated the development process leading up to this point. The result is a ready-to-use artifact that can be directly uploaded into SAC.
The final step was to bring everything into SAP Analytics Cloud. Using the Widget Add-Ons section in SAC, I uploaded the generated files by simply adding the index.json and the ZIP archive created by Claude Code. What makes this step important is that nothing had to be adjusted manually. The structure generated earlier fit perfectly with SACβs expectations, which meant the add-on could be integrated without any additional fixes. At this point, SAC takes over. It handles the execution, rendering, and integration of the add-on within the Story environment. Claude Code supported the entire development journey up to this point, but SAC remains the platform where the final value is delivered. The upload process itself was straightforward, which made it easy to go from development to actual usage within minutes.
I completed the upload by selecting the generated files directly within SAC. I provided the index.json as the main definition file and the ZIP archive as the resource bundle containing the implementation. What stood out here was how seamlessly everything fit together. The files created by Claude Code aligned exactly with what SAC expects in this upload dialog. There was no need for manual adjustments, renaming, or restructuring. The add-on could be created directly from the generated artifacts. SAC handles the registration and integration of the add-on at this point, while Claude Code ensured that everything leading up to this step was prepared correctly. This made the transition from development to deployment extremely smooth, reducing friction to almost zero.
After completing the upload, the widget add-on appeared in the SAC Widget Add-Ons list. The entry showed the add-on name, description, version, vendor, and resource file host, exactly as defined in the generated metadata. What stood out to me in this step was that the add-on was now visible as a registered entry within SAC. This confirmed that the upload and registration had been completed successfully.
Then I opened the SAC Story where I wanted to use the add-on. The Story already contained a horizontal bar chart in its standard form. At this point, the bars were still rendered with the default SAC appearance, without rounded edges. This view served as the starting point before applying the add-on.
I selected the chart in edit mode and opened the Builder panel on the right-hand side. From there, I navigated to the Custom Add-Ons section, enabled custom add-ons, and prepared to add the widget add-on to the selected chart. This is the point where the standard SAC chart can be connected with the add-on that was uploaded earlier.
The Add Add-On dialog was opened. Within the dialog, the Type was set to Plot Area (General), and the previously uploaded add-on βRounded Bar Chart Add-on (v1.0.0)β was selected from the list. This prepares the add-on to be applied to the chart.
The add-on was successfully applied to the chart. The bar chart now shows rounded edges instead of the default straight bars. In the Builder panel, the add-on appears under Custom Add-Ons as active for the chart. This confirms that the add-on is working and directly influencing the chartβs visual rendering.
After successfully applying the first add-on, I went back to Claude Code to start a second experiment. We can of course change the curves but letβs do something different. This time, I changed the goal completely. Instead of rendering a bar, I asked for a visual representation using bikes that should reflect the value. The prompt shows how quickly the direction can be changed. Rather than staying with a simple shape adjustment, I now moved to a more creative add-on idea and asked Claude Code to propose a suitable approach, for example using SVGs.
Claude Code then proposed how the bike representation should map to the underlying data values. It offered different scaling options, with the recommended approach being proportional to the longest bar, meaning the largest value defines how many bikes can fit, and all other values scale accordingly. This step defines the logic behind the visual encoding, ensuring that the bike representation remains consistent and comparable across all data points.
Claude Code next asked how the data values should be displayed alongside the bike visualization. It provided options to either show the numeric value as a label next to the bikes, or to display only the visual representation without labels. This defines whether the chart remains purely visual or combines visual elements with precise numeric information for better readability.
Claude Code then proposed whether a settings panel should be included for the add-on. The panel would allow control over parameters such as the maximum number of bikes displayed and the size of the bike icons. This defines how flexible and configurable the add-on should be, either with user-controlled settings or with fixed default behavior.
Claude Code summarized all previously defined decisions and translated them into a concrete implementation plan. It confirmed the selected options, proportional scaling based on the longest value, showing value labels, and including a settings panel for configuration. Based on this, it outlined the structure of the new add-on, including the required files such as the configuration JSON, the main visualization component, the settings panel, and a packaged archive for SAC upload. This marks the transition from design decisions to actual implementation, where the add-on is ready to be generated.
Claude Code generated the complete add-on automatically. It created all required files, including the configuration, the main visualization component, and the settings panel, and packaged them into a ZIP file ready for upload to SAC. The output also confirms how the add-on works. Each bar is replaced by a row of SVG bike icons, scaled proportionally to the data, with optional value labels and configurable settings such as icon size and maximum number of bikes. This demonstrates how quickly a fully functional custom visualization can be built and prepared for immediate use in SAC.
I then verified the generated files in the local folder. All required artifacts were created successfully, including the index.json, the main visualization file, the builder panel script, and the packaged Archive.zip. This confirmed that the add-on was fully prepared and ready for upload into SAC.
I returned to the Widget Add-Ons section in SAC to upload the newly created add-on. I selected Create and provided the required files, the index.json and the Archive.zip, using the file browser. This completed the technical handover from local development to SAC, making the new add-on available for use in stories.
The new add-on then appeared in the Widget Add-Ons list. The Bike Isotype Chart Add-on was now successfully registered in SAC, alongside the previously created add-on. This confirmed that the upload was successful and the add-on was now available to be used in stories.
Next, I removed the previously applied add-on from the chart. Within the Custom Add-Ons section, I clicked the remove icon next to the active add-on.
I then saved the story after removing the previous add-on. Using the Save option in the toolbar, I ensured that the current state of the story, without any add-on applied, was persisted.
To apply the new visualization, I opened Add Add-On again in the Custom Add-Ons section and selected the Bike Isotype Chart Add-on (v1.0.0) from the list. At this point, the chart is set up to use the new bike-based representation instead of the standard bar rendering.
To confirm the selection, I clicked OK in the add-on dialog. This action applies the Bike Isotype Chart Add-on to the chart and triggers the new rendering logic.
Immediately after confirming, the chart updates and renders the new visualization. The standard bars are now replaced by rows of bike icons, scaled according to the data values, with the numeric value shown next to them. This is the final result, a fully customized visual built via a SAC Widget Add-On, created end to end with Claude Code.
The custom add-on is now successfully applied and can be managed directly in the builder panel. From here, you can open the settings of the add-on via the edit icon to adjust behavior, styling, or scaling logic, depending on how the widget was implemented. This gives you full control over how the visualization behaves, turning a standard SAC chart into a fully customizable, application-like component.
You can now fine tune the visualization using the add-on settings panel. Adjust the scaling logic by defining how many icons represent the highest value, for example the maximum number of bikes for the longest bar. All other values will automatically scale proportionally. In addition, you can control the appearance, such as icon size and whether numeric labels are displayed. Once everything is configured, confirm your changes to apply the updated visualization.
Finally, validate the result by interacting with the chart. Hover over any bar to display the exact value via tooltip. Despite the custom visualization with icons, all standard SAC interactions remain fully intact, including tooltips, filtering, and context awareness. This confirms that your custom add-on is not only visually enhanced but also fully integrated into the native analytics experience.
Overall, this experiment showed that AI can provide very practical support when building SAC Widget Add-ons. SAC remains the actual platform and framework, while Claude Code helps structure the process, clarify design decisions, and generate the required implementation artifacts.
What I found most valuable was not just the code generation itself, but the guided workflow from idea to working result. Although I described the process here in much greater detail, the complete exercise itself took only around 15 minutes from start to finish.
For this experiment, I used Claude Code together with the Superpowers plugin (https://claude.com/plugins/superpowers), which adds a collection of predefined skills and workflows that help structure development tasks such as planning, implementation, and validation.
If you like this blog, please check also the second part of this short series: "π AI & Claude Code Experiment (Part 2): Building an SAP Analytics Cloud Custom Widget".
Kind Regards,
Adem