Any observable change a function causes beyond returning its output value — writing to a database, modifying global state, logging, making a network request.
In practice: Pure functions have no side effects, making them trivial to test and memoize. Managing where and when side effects happen is one of the core design problems in larger codebases — React hooks like `useEffect` exist specifically to contain them.