Skip to content
AI & Agents
Skill

/frappe-core-utils

Use when working with utility functions in Frappe v14-v16. Covers frappe.utils.* for date/time, number/money, string, validation, and file path operations. Prevents reinventing stdlib alternatives that break timezone awareness, locale formatting, or multi-tenancy. Keywords:

From plugin
frappe-claude-skill-package
17861 skills
Install
$ npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-core-utils --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/frappe-core-utils

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when working with utility functions in Frappe v14-v16. Covers frappe.utils.* for date/time, number/money, string, validation, and file path operations. Prevents reinventing stdlib alternatives that break timezone awareness, locale formatting, or multi-tenancy. Keywords:

SKILL.md

frappe-core-utils.SKILL.md
name: frappe-core-utils
description: >
  Use when working with utility functions in Frappe v14-v16. Covers
  frappe.utils.* for date/time, number/money, string, validation, and
  file path operations. Prevents reinventing stdlib alternatives that
  break timezone awareness, locale formatting, or multi-tenancy.
  Keywords: frappe.utils, nowdate, flt, cint, fmt_money, getdate,, date calculation, format number, money format, validate email, how to calculate days between.
  add_days, date_diff, validate_email, pretty_date, get_files_path.
license: MIT
compatibility: "Claude Code, Claude.ai Projects, Claude API. Frappe v14-v16."
metadata:
  author: OpenAEC-Foundation
  version: "3.0"

Frappe Utility Functions

Quick Reference: Python

| Need | Function | Returns | |------|----------|---------| | Current date | `nowdate()` / `today()` | `datetime.date` | | Current datetime | `now_datetime()` | `datetime.datetime` | | Parse date string | `getdate(str)` | `datetime.date` | | Parse datetime string | `get_datetime(str)` | `datetime.datetime` | | Add days | `add_days(date, n)` | `datetime.date` | | Add months | `add_months(date, n)` | `datetime.date` | | Date difference | `date_diff(end, start)` | `int` (days) | | Format for user | `format_date(dt)` | `str` (user locale) | | Relative time | `pretty_date(dt)` | `str` ("2 hours ago") | | Safe float | `flt(val, precision)` | `float` | | Safe int | `cint(val)` | `int` | | Safe string | `cstr(val)` | `str` | | Safe bool | `sbool(val)` | `bool` | | Safe division | `safe_div(a, b)` | `float` [v15+] | | Money format | `fmt_money(amt, currency)` | `str` | | Money in words | `money_in_words(amt, cur)` | `str` | | Strip HTML | `strip_html(text)` | `str` | | List to prose | `comma_and(items)` | `str` ("a, b, and c") | | Validate email | `validate_email_address(e)` | `str` or `""` | | Validate URL | `validate_url(url)` | `bool` | | Parse JSON | `parse_json(s)` | `Any` | | Files path | `get_files_path(is_private)` | `str` | | Site path | `get_site_path(*parts)` | `str` | | Unique list | `unique(seq)` | `list` | | Hash | `generate_hash(s, length)` | `str` |

> **ALL imports**: `from frappe.utils import nowdate, flt, ...` in controllers/whitelisted methods. > In **Server Scripts**: Use `frappe.utils.nowdate()` directly — NO import statements allowed.

---

Decision Tree: "Which function do I use?"

Need a date/time value?
├─ Current date → nowdate() or today()
├─ Current datetime → now_datetime()
├─ Parse a string → getdate() or get_datetime()
├─ Add/subtract time → add_days(), add_months(), add_to_date()
├─ Difference → date_diff() (days), month_diff(), time_diff_in_seconds()
├─ Period boundary → get_first_day(), get_last_day(), get_quarter_start()
└─ Display to user → format_date(), format_datetime(), pretty_date()

Need a number?
├─ Convert safely → flt(), cint(), cstr(), sbool()
├─ Round → rounded() (banker's rounding)
├─ Safe divide → safe_div(a, b, default=0) [v15+]
├─ Format money → fmt_money(amount, currency)
└─ Money to words → money_in_words(amount, currency)

Need string processing?
├─ HTML → strip_html(), escape_html(), is_html()
├─ Join list → comma_and(), comma_or(), comma_sep()
├─ Markdown ↔ HTML → to_markdown(), md_to_html()
└─ Mask sensitive → mask_string(input, show_first=4) [v16+]

Need validation?
├─ Email → validate_email_address(email, throw=False)
├─ URL → validate_url(url, valid_schemes=["https"])
├─ Phone → validate_phone_number(phone, throw=False)
├─ JSON → validate_json_string(s)
└─ IBAN → validate_iban(iban) [v16+]

Need file/path?
├─ Public files → get_files_path()
├─ Private files → get_files_path(is_private=True)
├─ Site directory → get_site_path("private", "backups")
├─ Bench root → get_bench_path()
└─ File size → get_file_size(path, format=True)

---

Critical Anti-Patterns

NEVER use Python stdlib when frappe.utils exists

| NEVER (stdlib) | ALWAYS (frappe.utils) | Why | |----------------|----------------------|-----| | `datetime.datetime.now()` | `now_datetime()` | Ignores system timezone | | `datetime.date.today()` | `nowdate()` | Ignores system timezone | | `float(val)` | `flt(val, precision)` | Crashes on None/empty | | `int(val)` | `cint(val)` | Crashes on None/empty | | `round(val, 2)` | `rounded(val, 2)` | Inconsistent rounding | | `val1 / val2` | `safe_div(val1, val2)` | ZeroDivisionError [v15+] | | `json.loads(s)` | `parse_json(s)` | Crashes on None/empty | | `json.dumps(obj)` | `frappe.as_json(obj)` | Inconsistent serialization | | `"{:,.2f}".format(a)` | `fmt_money(a, currency)` | Ignores locale/currency | | `os.path.join(...)` | `get_site_path(...)` | Breaks multi-tenancy | | `", ".join(items)` | `comma_and(items)` | No localized "and" | | `dt.strftime(fmt)` | `format_date(dt)` | Ignores user preference | | `re.sub(r'<.*?>', '', h)` | `strip_html(h)` | Misses edge cases |

Server Script Sandbox

# ❌ NEVER in Server Scripts
from frappe.utils import nowdate, flt
import json

# ✅ ALWAYS in Server Scripts (no imports allowed)
today = frappe.utils.nowdate()
amount = frappe.utils.flt(doc.amount, 2)
data = frappe.parse_json(doc.json_field)

---

JavaScript Quick Reference

| Need | Function | |------|----------| | Escape HTML | `frappe.utils.escape_html(txt)` | | HTML to text | `frappe.utils.html2text(html)` | | Check if HTML | `frappe.utils.is_html(txt)` | | Parse JSON | `frappe.utils.parse_json(str)` | | Validate URL | `frappe.utils.is_url(txt)` | | Title case | `frappe.utils.to_title_case(str)` | | Join with "and" | `frappe.utils.comma_and(list)` | | Unique array | `frappe.utils.unique(list)` | | Copy clipboard | `frappe.utils.copy_to_clipboard(txt)` | | Scroll to element | `frappe.utils.scroll_to(el)` | | Is mobile | `frappe.utils.is_mobile()` | | Throttle | `frappe.utils.throttle(fn, delay)` | | Debounce | `frappe.utils.debounce(fn, delay)` | | Format value | `frappe.format(value, df, options, doc)` | | Duration display | `frappe.utils.get_formatted_duration(secs)` |

-

Read more
Ships withfrappe-claude-skill-package

60 deterministic Claude AI skills for Frappe Framework & ERPNext v14-v16 development and operations

Get the whole plugin
Stats
178
Stars
53
Forks
Maintained
Maintenance
Python
Language
2mo ago
Last commit
8mo ago
Created
13d ago
Added

Repo: Impertio-Studio/Frappe_Claude_Skill_Package