One way to avoid limits without losing too much is to teach the calculus of finite differences. Conceptually, the move from numbers to lists-of-numbers as first-class mathematical objects is easier than the move from numbers to real-valued-functions-of-a-real-variable, and the easier move also forms a good stepping stone to the harder one. One can develop the calculus of finite differences mutatis mutandis and thereby make the transition to infinitesimal calculus essentially painless. (So, for example, one should work not with polynomials per se, but with linear combinations involving rising or falling powers).
All the black box rules have their analogues, and all are reasonably easy to see and/or prove. Passing the limit, when it happens, comes as a welcome simplification.
Aside from the conceptual challenge of functions themselves, students find limits difficult because of their quantifier complexity. I have never understood why standard algebra pedagogy suppresses quantifiers, thus, for example, leaving many students unable to distinguish between unknowns (literals bound by existential quantifiers), variables (literals bound by universal quantifiers) and constants (literals that belong to the language itself). Students who miscalculate the derivative of $\pi^2$, mentioned elsewhere, don't get this distinction. People who become mathematicians usually "got it" without anyone spelling all this out, and then they learned about quantifiers studying logic in college, so they regard quantifiers as sophisticated and advanced. But most students don't "get it," and I think this accounts for the huge attitude downturn when they get to algebra.