# Do's and Don'ts when developing First Project with Ignition?

**URL:** <https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592>\
**Category:** General Discussion\
**Created:** [July 23, 2024, 8:55am UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592 "2024-07-23T08:55:09Z")\
**Posts on this page:** 14\
**Page:** 4

<div class="post-metadata">

**Author:** ![tgarrison](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/tgarrison/32/80965_2.png) [@tgarrison](https://forum.inductiveautomation.com/u/tgarrison)\
**Post date:** [May 4, 2026, 1:07pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/65 "2026-05-04T13:07:07Z")

</div>

I use session.custom to handle "global" variables for stuff that we use across many customers. Stuff like Hand/Off/Auto - some customers prefer different words, so session.custom is where I store those lookups, and everywhere that needs them just refers there. So 1 spot to change and it affects all the buttons/statuses etc.

---

<div class="post-metadata">

**Author:** ![Brian\_Stilson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/brian_stilson/32/73410_2.png) [@Brian\_Stilson](https://forum.inductiveautomation.com/u/Brian_Stilson)\
**Post date:** [June 17, 2026, 11:33am UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/66 "2026-06-17T11:33:15Z")

</div>

Seriously consider scalability with all of your projects. You never know when something you did is going to be deployed dozens, if not hundreds of times.

One of my big projects I've worked on started out as a simple Panelview Plus \> Ignition Edge update. I had heard rumors of a Cloud portion but at the time it wasn't part of my scope and we had a deadline. So I made quite a few decisions that weren't ideal at scale, but fine for a single-node Edge application running on a site by itself, providing visualization to a single PLC. Then it turned out my less-than-ideal Edge application had to scale, and run on a Cloud server, with potentially dozens and then hundreds of tenants. As it grew, the decisions I made came back to bite me, and they had to be streamlined and made scalable, especially as more and more features were asked for. Of course, with every job, I look back and have regrets and "if I knew then what I know now" moments, but it never hurts to have less of them!

---

<div class="post-metadata">

**Author:** ![msteele](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/msteele/32/77889_2.png) [@msteele](https://forum.inductiveautomation.com/u/msteele)\
**Post date:** [June 17, 2026, 3:36pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/67 "2026-06-17T15:36:21Z")

</div>

At the same time, avoid the temptation to over-abstract and make everything reusable at first. I used to do this with embedded views or components for everything, components that were usable in a variety of contexts and situations, etc. And at some point I was just making more work for myself and producing a lower-performance front end. There is a balance to be sought.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [June 17, 2026, 3:56pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/68 "2026-06-17T15:56:32Z")

</div>

The balance between YANGI and abstracting appropriately is one you only really get with experience and failure. Knowing too if the project is going to be deployed elsewhere does also help inform you on these decisions. Try to do things with best practices as best you can, keep your code readable, keep your layers separate (gui from business even in scripting) will help keep things testable and extensible for when the client says "oh wait acutally can we do this other thing way".

But experience really will be the best teacher here imo.

---

<div class="post-metadata">

**Author:** ![paul.longtine](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul.longtine/32/10599_2.png) [@paul.longtine](https://forum.inductiveautomation.com/u/paul.longtine)\
**Post date:** [July 22, 2026, 6:08pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/69 "2026-07-22T18:08:49Z")

</div>

I don't think it has been mentioned here just yet...

When working with strings in any Jython scripts, if you ever have to format, concatenate, or involve any operation that might include a unicode codepoint, use unicode strings explicitly!

Instead of using snippets that look like this:

```python
def my_awesome_string_tool(user_name, user_id):
    # Unicode can come from anywhere, but string encoding depends on the DB!
    notes = system.db.execScalar('getNotes', {'noteid':4})
    # The returned string may be less than ideal to work with...
    return "My user {} has these notes: {}".format(user_name, notes)

```

Instead, a single character change may improve outcomes:

```python
def my_awesome_unicode_string_tool(user_name, user_id):
    # Unicode can come from anywhere, but it doesn't matter because we use unicode strings!
    notes = system.db.execScalar('getNotes', {'noteid':4})
    # The returned string is now explicitly a unicode string, and won't hurt you!
    return u"My user {} has these notes: {}".format(user_name, notes)

```

I've been bitten by taking unicode input and formatting it within a jython2.7 string. Don't be like me and use unicode strings!

---

<div class="post-metadata">

**Author:** ![Alejandro\_Alaco](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/alejandro_alaco/32/59849_2.png) [@Alejandro\_Alaco](https://forum.inductiveautomation.com/u/Alejandro_Alaco)\
**Post date:** [July 29, 2026, 11:00am UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/70 "2026-07-29T11:00:03Z")

</div>

I use that all the time for Spanish characters

---

<div class="post-metadata">

**Author:** ![gunnar.newell](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/gunnar.newell/32/87635_2.png) [@gunnar.newell](https://forum.inductiveautomation.com/u/gunnar.newell)\
**Post date:** [October 29, 2026, 3:14pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/72 "2026-10-29T15:14:22Z")

</div>

A theme seems to be put everything into scripts (the script library instead of on components), but then there is also a theme of only using scripts where necessary, and focusing on property bindings and expressions because they're faster.

What are some instances where scripts are necessary, and what are instances where expressions are sufficient? At what point is the cutoff? Is it just the amount of complicated logic?

---

<div class="post-metadata">

**Author:** ![travisaggiebrown](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/travisaggiebrown/32/85824_2.png) [@travisaggiebrown](https://forum.inductiveautomation.com/u/travisaggiebrown)\
**Post date:** [October 29, 2026, 3:30pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/73 "2026-10-29T15:30:21Z")

</div>

if you have to write to a property or tag you have to use a script, most things involving arrays and datasets will also require a script. a good rule of thumb is if you don't need to write results to anything other than the property the binding itself is on, use expressions.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 29, 2026, 4:21pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/74 "2026-10-29T16:21:32Z")

</div>

> [@gunnar.newell](#):
>
> put everything into scripts

> [@gunnar.newell](#):
>
> script library instead of on components

Those two items are **orthogonal**. The latter is a recommendation to maximize maintainability, and leverage certain performance advantages, **when** you decide to use a script at all.

I strongly encourage you to **NOT** put everything into scripts. They are the **least** performant way to move information around. But most flexible. Use where **needed**.

> [@travisaggiebrown](#):
>
> most things involving arrays and datasets will also require a script

A big chunk of my Integration Toolkit is devoted to making this untrue--enabling expressions for complex constructs from datasets and other repetitive data.

---

<div class="post-metadata">

**Author:** ![gunnar.newell](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/gunnar.newell/32/87635_2.png) [@gunnar.newell](https://forum.inductiveautomation.com/u/gunnar.newell)\
**Post date:** [October 29, 2026, 4:53pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/75 "2026-10-29T16:53:01Z")

</div>

My confusion came from the fact that they are very different, where can I find your Toolkit?

---

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [October 29, 2026, 4:55pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/76 "2026-10-29T16:55:29Z")

</div>

Download from [here](https://forum.inductiveautomation.com/t/automation-professionals-integration-toolkit-module/74934/359)

There is a wiki thread to help with common tasks [here](https://forum.inductiveautomation.com/t/integration-toolkit-solutions-wiki/105080)

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [October 29, 2026, 5:12pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/77 "2026-10-29T17:12:48Z")

</div>

> [@gunnar.newell](#):
>
> At what point is the cutoff?

If you need more than a single [expression](https://en.wikipedia.org/wiki/Expression_(computer_science)), you need something more than the expression language (by definition).

Note that Phil's toolkit is entirely optional. I can't argue with his performance gains, but [there's a saying](https://wiki.c2.com/?PrematureOptimization) about premature optimization. Make your project(s) in the way that you and whoever comes after you can **maintain** them. In my opinion, only reach to the advanced functionality offer by Phil's module when

1. You actually **need** the extra performance
2. You are sufficiently comfortable in Ignition that you understand the cost/benefit analysis

Don't just blindly hear "scripts are slow, expressions are fast" and think Phil's module is a panacea for all possible problems you're going to face in Ignition, especially Perspective.

---

<div class="post-metadata">

**Author:** ![Steve\_Laubach](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/steve_laubach/32/60900_2.png) [@Steve\_Laubach](https://forum.inductiveautomation.com/u/Steve_Laubach)\
**Post date:** [October 29, 2026, 5:53pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/78 "2026-10-29T17:53:39Z")

</div>

IMO the same thing applies to map transforms. I use map transforms a lot when I feel the performance impact is minimal because I feel like the system will be more intuitive to support down the road. I try to build everything so that anyone can support it so that anyone can support it.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 29, 2026, 6:31pm UTC](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592/79 "2026-10-29T18:31:44Z")

</div>

> [@paul-griffith](#):
>
> Phil's module is a panacea

I like this out-of-context quote. I may be a bit biased.

[Previous page](https://forum.inductiveautomation.com/t/dos-and-donts-when-developing-first-project-with-ignition/93592.md?page=3)
