Power Automate vs Custom Code (Node.js): A Decision Framework for SMBs
Low-code and code-first aren't rivals. They're tools for different problems. Here's how we decide, four real workflows split step by step, and the hybrid that tends to outperform either alone.
SBy Shuvam, Founder of KodeBizUpdated
The thesis: let the shape of the problem pick the tool
The Power Automate vs custom Node debate is usually framed as low-code versus real code. That framing is wrong. The right question is: how much of your workflow is connecting Microsoft 365 systems that already have connectors, versus enforcing logic that those connectors can't express?
Power Automate wins when the work is orchestration across SaaS you already own: approvals, notifications, file routing, SharePoint and Dataverse CRUD. Custom Node wins when the work is computation, complex state, or rules that must be testable, versioned, and auditable line by line. Most real SMB systems need both, so the durable answer is rarely one or the other.
Power Automate vs custom Node.js, side by side
The table below is the checklist we use during a requirement study. Read it row by row against one workflow at a time, not against your whole system: the same project usually lands on both sides.
| Power Automate | Custom Node.js service | |
|---|---|---|
| Best for | Approvals, notifications and moving records between Microsoft 365 apps | Calculations, dense business rules and high-volume data processing |
| Who builds and changes it | A trained maker or developer, in a visual designer | A developer, in a code editor, through a reviewed pull request |
| Testing | Manual test runs and run history; no unit test layer | Unit and integration tests that run on every change |
| Version control | Solutions can be exported to source control, but a flow's diff is a JSON definition that is hard to review | Plain source files in Git, with line-by-line diffs and code review |
| Errors and retries | A configurable retry policy per action, plus run-after branches for failure paths | Whatever you design: queues, idempotency keys, dead-letter handling |
| Throughput and limits | Daily request allowances set by licence, connector throttling, and a 30-day maximum run duration | Bounded by your hosting and by the APIs the service calls |
| Licensing model | Per-user or per-flow plans; premium connectors, including HTTP, need a premium licence | No per-flow licence; the cost is hosting and engineering time |
| Reaching on-premises systems | Through the on-premises data gateway, for the connectors that support it | Runs inside your network, next to the system it talks to |
| Audit trail | Run history kept for a limited window; useful for debugging, not an audit log | An append-only log you design, kept as long as your policy requires |
| Who maintains it | A Microsoft 365 admin or maker can read and adjust simple flows | A developer makes changes, with the tests as the safety net |
Where low-code wins
If your team lives in Microsoft 365, Power Automate removes a lot of plumbing. Connectors, SSO, and the SharePoint/Dataverse/Teams surface are already wired, so an approval flow or a notification chain is mostly configuration rather than custom code. For King Stubb & Kasiva's multi-office law-firm ERP, a four-step invoice approval chain ran entirely on Power Automate, and keeping that routing logic in low-code is what makes it legible to reviewers later. A flow a non-developer can read is a flow they can sign off on.
- Human-in-the-loop approvals and routing across Microsoft 365
- Event glue: a record changes here, notify or sync there
- Document workflows over SharePoint, with permissions you already manage
- Workflows business users must read and tweak without engineering
Power Automate limitations: where it hits a wall
Low-code degrades fast once logic gets dense. Branching that would be a few lines of TypeScript becomes a sprawling, hard-to-review flow. There's no real unit test layer, diffs in source control are opaque, and complex loops or data transforms fight the runtime. Statutory or financial calculations, the kind where a wrong branch is a liability, belong in code you can test.
We saw the boundary on a Section 138 cheque-bounce case manager: the statutory deadlines under the Negotiable Instruments Act 1881 were auto-computed in custom services, while Power Automate handled the surrounding notifications. The rule engine needed real tests and an audit trail; the glue did not. Splitting on that line is the usual pattern.
- Date and money math where a wrong branch is a real liability
- Logic that needs unit tests and reviewable source-control diffs
- High-volume or latency-sensitive processing
- Rules you expect to version and audit over time
Four SME workflows, split step by step
Purchase approval with a Tally voucher. A purchase request is raised in a Power Apps form or a SharePoint list. Power Automate routes it to the department head, then to accounts above a set amount, with reminders and an approval card in Teams for each approver. That part is pure flow. Posting the purchase voucher is not: TallyPrime usually runs on a desktop or a local server, and a cloud flow cannot reach it directly. A small Node service on the same network takes the approved request, checks that the ledger, stock item and GST rate exist in Tally, posts the voucher and writes the voucher number back. If Tally is closed or a ledger name does not match, the service holds the request and says why, instead of the flow failing silently.
GST invoice generation. The invoice itself is computed in code. Whether a supply is intra-state (CGST plus SGST) or inter-state (IGST) depends on the place of supply, rounding has to match what accounts expect, and where e-invoicing applies, the payload sent for an IRN follows a strict schema. Those are rules with tests. Power Automate then does what it is good at: saving the PDF to the customer's SharePoint folder, emailing it, and creating a follow-up task when the due date passes.
CRM lead routing. A lead arrives from the website form or a shared inbox. A flow creates the record, assigns it by region or product line, and posts it to the right sales channel in Teams. While the rules stay that simple, they live in the flow. When routing starts to depend on lead scoring, duplicate detection across contacts and accounts, or round-robin that respects leave and capacity, the decision moves into a service the flow calls, and the flow keeps the notification.
Document generation. For a standard letter or quote with fixed fields, the Word Online (Business) connector's Populate a Microsoft Word template action (a premium action) plus a PDF conversion is enough. Contracts with conditional clauses, repeating tables of variable length, or reference numbers that must never repeat are easier to get right in a Node service that renders the document from a template and records which version of each clause went out.
- In the flow: routing, reminders, approvals, Teams and email notifications, filing to SharePoint
- In code: tax and money calculations, posting to systems inside your network, dense routing rules, numbered documents
- At the boundary: one HTTP call per decision, with the result written back so the flow can carry on
Limits to check before a workflow goes into a flow
Most Power Automate projects that go wrong do so on limits nobody checked during scoping. None of these rule the platform out; they decide which steps belong in a flow and which licence the flow needs.
- Request limits: each licence carries a daily allowance of Power Platform requests, and every action counts, so a flow that loops over thousands of rows a day can run into it
- Run duration: a cloud flow run times out after 30 days, so long approval chains need a design for expiry and re-routing
- Premium connectors: HTTP, custom connectors and SQL Server need a premium licence, so the licensing plan is agreed together with the workflow
- Throttling: connectors such as SharePoint and Outlook have their own call limits, so bulk updates need batching or pacing
- On-premises reach: a cloud flow reaches systems inside your network only through the on-premises data gateway, and only for connectors that support it
Testing, version control and ALM in practice
Flows can be solution-aware: built inside a Dataverse solution, moved from development to test to production as a managed solution, and deployed with Power Platform pipelines. Connection references and environment variables keep credentials and URLs out of the flow definition. That is real application lifecycle management, and worth using from the first flow, not after the fifth.
What it does not give you is a test suite. You can run a flow with test data and read its run history, but you cannot assert that a rule returns the right answer for fifty edge cases on every change. A Node service can: tests run on every pull request, and a reviewer reads a line-level diff before anything reaches production. If a rule's failure would cost money or miss a legal deadline, that difference decides where it lives.
TCO and governance: the costs nobody quotes upfront
Power Automate looks cheaper because there's no server to run, but cost moves to licensing (premium connectors, per-flow plans) and to maintenance debt when flows grow past what a diagram can hold. Custom Node has hosting and engineering cost upfront, but after that each new rule is just one more tested function.
Governance cuts the other way. Power Automate gives you a managed runtime, tenant-level policies, and run history out of the box. Custom services give you control, but observability, deploys, and the audit trail become your responsibility. For anything compliance-sensitive, design the audit log as append-only from day one. That is a design choice we recommend, and you have to build it in yourself, since no connector provides it.
The hybrid that usually wins
Use Power Automate as the orchestration spine and custom Node for the decisions. Flows trigger on events, route humans, and write back to Microsoft 365; they call a custom service whenever real computation or audited logic is involved. The connector handles what it's good at; the code owns what must be tested.
Draw the line by asking: does this step need a unit test? If yes, it's a service call. If no, it's a flow action. That single question keeps low-code readable for business users and keeps risky logic under version control. It's also how we scope CRM, automation, and case-management builds for SMBs: during the requirement study, each step of the agreed workflow is marked as a flow action or a service call, so the split is settled in writing before either side is built.
Frequently asked
Is Power Automate cheaper than building a custom Node service?
Often at first, because there's no server to run and the connectors are already built. But cost shifts to premium-connector licensing and to maintenance once flows grow past what a diagram can hold. Custom Node costs more upfront in hosting and engineering, but adding a new tested rule stays cheap. Compare total cost of ownership over the system's whole life.
Can I use both Power Automate and custom Node together?
Yes, and for most SMB systems that hybrid is the strongest answer. Let Power Automate handle event orchestration, approvals, and Microsoft 365 read/write, and have it call custom Node services for any logic that needs unit tests, versioning, or a real audit trail. A simple rule of thumb: if a step needs a unit test, it belongs in code, not in a flow.
When should I avoid low-code entirely for a workflow step?
Avoid it for statutory or financial calculations, dense branching, high-volume or latency-sensitive processing, and any rule you expect to version and audit over time. Those need reviewable diffs and tests that a flow runtime can't give you. Keep the surrounding notifications and human routing in low-code, and move the risky computation into a custom service.
Is the HTTP action in Power Automate a premium connector?
Yes. The HTTP connector, and any custom connector you build around your own API, is premium, so the flow needs a premium licence such as Power Automate Premium or a per-flow Process licence. That matters for the hybrid design: if flows call custom Node services, agree the licensing for those flows during the requirement study, alongside the workflow itself.
How does a Power Automate flow call a custom Node.js service?
Through the HTTP action or a custom connector that wraps the service's API. The flow sends the record, the service runs the tested logic and returns a result, and the flow carries on with routing and notifications. Secure the service with Microsoft Entra ID rather than a shared key, and make every call idempotent, so a retry from the flow's retry policy cannot post the same thing twice.
Can Power Automate post vouchers directly into Tally?
Not from the cloud on its own. TallyPrime usually runs on a desktop or local server and accepts XML requests from inside that network, which a cloud flow cannot reach. The reliable pattern is a small service on the same network that receives the approved request, validates ledgers and stock items, posts the voucher and reports the result back to the flow. Desktop flows can drive Tally's screens, but they break when a screen changes.
Sources
Power Automate approval workflow examples
Approval flows we build on Power Automate, from purchase requests to multi-level sign-off.
ArticlePower Apps vs custom development
The same decision one layer up: when an app belongs on Power Apps and when it needs custom code.
ServicePower Automate
Automate approvals and SLA timers across the Microsoft 365 tools you already use.
ServiceCustom Node services
Code-first Node.js services for the jobs low-code can't handle.
ServiceApproval workflows
Multi-stage approvals with routing, escalation, and a full audit trail.
ServiceIntegration layer
Keep your systems reliably in sync long after launch.