We describe an algorithm for automatic inline expansion across module boundaries that works in the presence of higher-order functions and free variables; it rearranges bindings and scopes as necessary to move nonexpansive code from one module to an- other. We describe -- and implement -- the algorithm as transformations on Lambda-calculus. Our inliner interacts well with separate compilation and is efficient, robust, and practical enough for everyday use in the SML/NJ compiler. Inlining improves performance by 4-8% on existing code, and makes it possible to use much more data abstraction by consistently eliminating penalties for modularity.